在dataframe中创建字典类型列

fut*_*110 7 python pyspark spark-dataframe

考虑以下数据帧:

------------+--------------------+
|id|          values
+------------+--------------------+
|          39|a,a,b,b,c,c,c,c,d
|         520|a,b,c
|         832|a,a
Run Code Online (Sandbox Code Playgroud)

我想将其转换为以下DataFrame:

------------+--------------------+
|id|          values
+------------+--------------------+
|          39|{"a":2, "b": 2,"c": 4,"d": 1}
|         520|{"a": 1,"b": 1,"c": 1}
|         832|{"a": 2}
Run Code Online (Sandbox Code Playgroud)

我尝试了两种方法:

  1. 将数据帧转换为rdd.然后我将值列映射到frequancy计数器函数.但是我将rdd转换回数据帧时遇到错误

  2. 使用udf基本上做与上面相同的事情.

我想拥有一个字典列的原因是将它作为json加载到我的一个python应用程序中.

小智 10

您可以使用返回MapType列的udf执行此操作.

from pyspark.sql.types import MapType, StringType, IntegerType
from collections import Counter

my_udf = udf(lambda s: dict(Counter(s.split(','))), MapType(StringType(), IntegerType()))
df = df.withColumn('values', my_udf('values'))
df.collect()

[Row(id=39, values={u'a': 2, u'c': 4, u'b': 2, u'd': 1}),
 Row(id=520, values={u'a': 1, u'c': 1, u'b': 1}),
 Row(id=832, values={u'a': 2})]
Run Code Online (Sandbox Code Playgroud)


Jos*_*emy 0

我无法准确获得您需要的输出,但我非常接近。这是我能得到的:

from pyspark.sql.functions import explode, split
counts = (df.select("id", explode(split("values", ",")).alias("value")).groupby("id", "value").count())
counts.show()
Run Code Online (Sandbox Code Playgroud)

输出:

+---+-----+-----+
| id|value|count|
+---+-----+-----+
|520|    a|    1|
|520|    b|    1|
|520|    c|    1|
| 39|    a|    2|
| 39|    b|    2|
| 39|    c|    4|
| 39|    d|    1|
|832|    a|    2|
+---+-----+-----+
Run Code Online (Sandbox Code Playgroud)

也许有人可以添加所需的内容来获得您需要的输出。希望能帮助到你。