PySpark将datafram中“map”类型的列转换为多个列

2024-05-15 11:05:36 发布

您现在位置:Python中文网/ 问答频道 /正文

输入

我有一列Parameters类型map的表单:

>>> from pyspark.sql import SQLContext
>>> sqlContext = SQLContext(sc)
>>> d = [{'Parameters': {'foo': '1', 'bar': '2', 'baz': 'aaa'}}]
>>> df = sqlContext.createDataFrame(d)
>>> df.collect()
[Row(Parameters={'foo': '1', 'bar': '2', 'baz': 'aaa'})]

输出

我想在pyspark中重塑它,使所有键(foobar等)都是列,即:

[Row(foo='1', bar='2', baz='aaa')]

使用withColumn工作:

(df
 .withColumn('foo', df.Parameters['foo'])
 .withColumn('bar', df.Parameters['bar'])
 .withColumn('baz', df.Parameters['baz'])
 .drop('Parameters')
).collect()

但是我需要一个不显式提到列名的解决方案,因为我有很多列名。

架构

>>> df.printSchema()

root
 |-- Parameters: map (nullable = true)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = true)

Tags: truemapdfstringfoobarbazpyspark
1条回答
网友
1楼 · 发布于 2024-05-15 11:05:36

由于MapType的键不是架构的一部分,因此必须首先收集这些键,例如:

from pyspark.sql.functions import explode

keys = (df
    .select(explode("Parameters"))
    .select("key")
    .distinct()
    .rdd.flatMap(lambda x: x)
    .collect())

当你有了这些,剩下的就是简单的选择:

from pyspark.sql.functions import col

exprs = [col("Parameters").getItem(k).alias(k) for k in keys]
df.select(*exprs)

相关问题 更多 >