PySpark转换类型' map'到数据框中的多个列

时间:2016-04-26 15:18:24

标签: python apache-spark dataframe pyspark apache-spark-sql

输入

我有Parameters的{​​{1}}列格式:

map

输出

我想在pyspark中重塑它,以便所有键(>>> 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'})] foo等)都是列,即:

bar

使用[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()

2 个答案:

答案 0 :(得分:13)

由于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)

答案 1 :(得分:0)

高性能解决方案

问题的约束之一是动态确定列名,这很好,但是要警告这可能真的很慢。这是避免输入和编写将快速执行的代码的方法。

cols = list(map(
    lambda f: F.col("Parameters").getItem(f).alias(str(f)),
    ["foo", "bar", "baz"]))
df.select(cols).show()
+---+---+---+
|foo|bar|baz|
+---+---+---+
|  1|  2|aaa|
+---+---+---+

请注意,这将运行一个选择操作。不要多次运行withColumn,因为那样会更慢。

仅当您知道所有地图键时,才可能实现快速解决方案。如果您不知道地图键的所有唯一值,则需要恢复到较慢的解决方案。

较慢的解决方案

可接受的答案是好的。我的解决方案性能更高,因为它不会调用.rddflatMap()

import pyspark.sql.functions as F

d = [{'Parameters': {'foo': '1', 'bar': '2', 'baz': 'aaa'}}]
df = spark.createDataFrame(d)

keys_df = df.select(F.explode(F.map_keys(F.col("Parameters")))).distinct()
keys = list(map(lambda row: row[0], keys_df.collect()))
key_cols = list(map(lambda f: F.col("Parameters").getItem(f).alias(str(f)), keys))
df.select(key_cols).show()
+---+---+---+
|bar|foo|baz|
+---+---+---+
|  2|  1|aaa|
+---+---+---+

将结果收集到驱动程序节点可能是性能瓶颈。最好将此代码list(map(lambda row: row[0], keys_df.collect()))作为单独的命令执行,以确保其运行速度不会太慢。

blog post详细介绍了该主题,并教您如何通过分析逻辑计划来分析预期的性能。