Pyspark DataFrame-将具有n个元素“键=值”的数组的列转换为n个新列

时间:2018-09-28 16:47:15

标签: apache-spark apache-spark-sql

我有以下数据框

+-------_--------------------------------------------+
| Col1                                               |
+------_---------------------------------------------+
|["field1=abc","field2=asd",....,"fieldN=zzz"]       |
|["field1=abc1","field2=asd1",....,"fieldN=zzz1"]    |  
|["field1=abc2","field2=asd2",....,"fieldN=zzz2"]    |  
| .................................................  |
+----------------------------------------------------+

对此

+-------_--------------------------------------------+
| field1 | field2 | ....        | fieldN             |
+------_---------------------------------------------+
|abc     | asd    |....         | zzz                |
|abc1    | asd1   |....         | zzz1               |
|abc2    | asd2   |....         | zzz2               |
| .................................................  |
+----------------------------------------------------+

我发现了一些类似的例子

df=df.withColumn('name', F.col('exploded').getItem(0))

但是由于我有很多字段,我希望使用更通用的东西

有什么主意吗?

1 个答案:

答案 0 :(得分:0)

假设您的列是一种结构类型,而不仅仅是一串JSON数据:

有两种选择。您可以在SQL中使用“ field。*”来选择所有子字段。在python中最简单的方法是在DataFrame上使用selectExpr方法。请注意,如果要维护其他字段,也可以选择它们。  例如:

>>> data = [
    ((1, 2, 3, 4),),
    ((4, 5, 6, 7),)
]

>>> df = spark.createDataFrame(sc.parallelize(data))

>>> df.printSchema()
root
 |-- _1: struct (nullable = true)
 |    |-- _1: long (nullable = true)
 |    |-- _2: long (nullable = true)
 |    |-- _3: long (nullable = true)
 |    |-- _4: long (nullable = true)

>>> df.show()
+------------+
|          _1|
+------------+
|[1, 2, 3, 4]|
|[4, 5, 6, 7]|
+------------+


>>> df2 = df.selectExpr("_1 as original", "_1.*")
>>> df2.show()
+------------+---+---+---+---+
|    original| _1| _2| _3| _4|
+------------+---+---+---+---+
|[1, 2, 3, 4]|  1|  2|  3|  4|
|[4, 5, 6, 7]|  4|  5|  6|  7|
+------------+---+---+---+---+

或者,DataFrame上的架构字段可用于确定所有字段及其类型以及任何子字段。然后,您可以使用这些名称来遍历它们,并像上面一样使用withColumn。例如:

>>> struct_field = next(f for f in df.schema if f.name == "_1")
>>> subfield_names = [f.name for f in struct_field.dataType.fields]
>>> print subfield_names
['_1', '_2', '_3', '_4']