通过切片/拆分存储在列表中的字段宽度值,将apache-spark数据帧字符串列拆分为多列

时间:2018-07-11 19:31:33

标签: scala apache-spark apache-spark-sql

我有一个看起来像这样的数据框

+--------------------
|       unparsed_data|
+--------------------
|02020sometext5002...
|02020sometext6682...

我需要把它分成这样的东西

+--------------------
|fips  | Name     | Id ...    
+--------------------
|02020 | sometext | 5002...
|02020 | sometext | 6682...

我有一个这样的列表

val fields = List(
  ("fips", 5),
  (“Name”, 8),
  (“Id”, 27)
  ....more fields
)

我需要吐出unparsed_data中的前5个字符并将其映射到fips,在unparsed_data中将其后的8个字符映射到Name,然后接下来的27个字符并将其映射到Id,依此类推。我需要分割以使用/引用列表中提供的文件长度来进行分割/切片,因为存在字段分配并且unparsed_data字段很长。

我的scala仍然很漂亮,我认为答案看起来像这样

df.withColumn("temp_field", split("unparsed_data", //some regex created from the list values?)).map(i => //some mapping to the field names in the list)

非常感谢任何建议/想法

2 个答案:

答案 0 :(得分:2)

您可以使用foldLeft遍历fields列表,以使用以下命令从原始DataFrame迭代创建列 substring。无论fields列表的大小如何,它都适用:

import org.apache.spark.sql.functions._

val df = Seq(
  ("02020sometext5002"),
  ("03030othrtext6003"),
  ("04040moretext7004")
).toDF("unparsed_data")

val fields = List(
  ("fips", 5),
  ("name", 8),
  ("id", 4)
)

val resultDF = fields.foldLeft( (df, 1) ){ (acc, field) =>
    val newDF = acc._1.withColumn(
      field._1, substring($"unparsed_data", acc._2, field._2)
    )
    (newDF, acc._2 + field._2)
  }._1.
  drop("unparsed_data")

resultDF.show
// +-----+--------+----+
// | fips|    name|  id|
// +-----+--------+----+
// |02020|sometext|5002|
// |03030|othrtext|6003|
// |04040|moretext|7004|
// +-----+--------+----+

请注意,Tuple2[DataFrame, Int]用作foldLeft的累加器,以同时承载经过迭代转换的DataFrame和substring的下一个偏移位置。

答案 1 :(得分:1)

这可以帮助您前进。根据您的需要,它的可变长度等会变得越来越复杂,而您没有声明。但是我可以认为使用列列表。

import org.apache.spark.sql.functions._

val df = Seq(
       ("12334sometext999")
       ).toDF("X")

 val df2 = df.selectExpr("substring(X, 0, 5)", "substring(X, 6,8)", "substring(X, 14,3)")

 df2.show

在这种情况下提供(您可以再次重命名cols):

+------------------+------------------+-------------------+
|substring(X, 0, 5)|substring(X, 6, 8)|substring(X, 14, 3)|
+------------------+------------------+-------------------+
|             12334|          sometext|                999|
+------------------+------------------+-------------------+