web-dev-qa-db-ja.com

Spark:文字列の列を配列に変換します

文字列として読み取られた列を配列の列に変換する方法は?すなわち、以下のスキーマから変換します

scala> test.printSchema
root
 |-- a: long (nullable = true)
 |-- b: string (nullable = true)

+---+---+
|  a|  b|
+---+---+
|  1|2,3|
+---+---+
|  2|4,5|
+---+---+

に:

scala> test1.printSchema
root
 |-- a: long (nullable = true)
 |-- b: array (nullable = true)
 |    |-- element: long (containsNull = true)

+---+-----+
|  a|  b  |
+---+-----+
|  1|[2,3]|
+---+-----+
|  2|[4,5]|
+---+-----+

可能な場合はscalaとpythonの実装を共有してください。 〜450列で、そのうちのいくつかをこの形式で指定したい現在、私はpysparkで次のように読んでいます:

df = spark.read.format('com.databricks.spark.csv').options(
    header='true', inferschema='true', delimiter='|').load(input_file)

ありがとう。

9
Nikhil Utane

いろいろな方法がありますが、

最善の方法は、split関数を使用してarray<long>にキャストすることです

data.withColumn("b", split(col("b"), ",").cast("array<long>"))

単純なUDFを作成して値を変換することもできます

val tolong = udf((value : String) => value.split(",").map(_.toLong))

data.withColumn("newB", tolong(data("b"))).show

お役に立てれば!

11
Shankar Koirala

[〜#〜] udf [〜#〜] を使用すると、正確に必要なスキーマが得られます。このような:

val toArray = udf((b: String) => b.split(",").map(_.toLong))

val test1 = test.withColumn("b", toArray(col("b")))

次のようなスキーマが得られます。

scala> test1.printSchema
root
 |-- a: long (nullable = true)
 |-- b: array (nullable = true)
 |    |-- element: long (containsNull = true)

+---+-----+
|  a|  b  |
+---+-----+
|  1|[2,3]|
+---+-----+
|  2|[4,5]|
+---+-----+

ファイル読み取り自体にスキーマを適用することに関しては、それは難しい作業だと思います。したがって、今のところ、DataFrameReadertestを作成した後に変換を適用できます。

これがお役に立てば幸いです!

2
himanshuIIITian

python(pyspark)の場合:

from pyspark.sql.types import *
from pyspark.sql.functions import col, split
test = test.withColumn(
        "b",
        split(col("b"), ",\s*").cast("array<int>").alias("ev")
 )
0