Python PySpark获取StructType输出以从列表计算分布 问题是:

Python PySpark获取StructType输出以从列表计算分布 问题是:,python,apache-spark,pyspark,apache-spark-sql,pyspark-dataframes,Python,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Dataframes,我有一列包含冗余值列表,我需要在PySpark数据帧的新列中将其转换为类似字典的格式 情景: 这是我的pyspark数据帧: A. C 所有课程 10 RDK [1, 1, 1, 2, 2] 10 美国西南大学 [1, 2, 2, 2, 2, 2, 2] 8. RDK [21, 21, 21, 21, 20] 8. RDJ [20, 20, 21] 10 RDK [45, 45, 45, 45, 2, 2, 2] 7. SSW [6, 6, 6, 19, 19] 您可以尝试以下方法: from

我有一列包含冗余值列表,我需要在PySpark数据帧的新列中将其转换为类似字典的格式

情景:

这是我的pyspark数据帧:

A. C 所有课程 10 RDK [1, 1, 1, 2, 2] 10 美国西南大学 [1, 2, 2, 2, 2, 2, 2] 8. RDK [21, 21, 21, 21, 20] 8. RDJ [20, 20, 21] 10 RDK [45, 45, 45, 45, 2, 2, 2] 7. SSW [6, 6, 6, 19, 19] 您可以尝试以下方法:

from pyspark.sql import functions as F, Window

result = my_df.withColumn(
    'all_classes',
    F.collect_list('Class').over(Window.partitionBy('A', 'C'))
).groupBy(
    'A', 'C', 'all_classes', 'Class'
).agg(
    F.count('Class').alias('cnt_class')
).groupBy(
    'A', 'C', 'all_classes'
).agg(
    F.map_from_entries(
        F.collect_list(F.struct('Class', 'cnt_class'))
    ).alias('distribution')
)

result.show(truncate=False)
+---+---+----------------------------------------+-------------------------+
|A  |C  |all_classes                             |distribution             |
+---+---+----------------------------------------+-------------------------+
|7  |SSW|[6, 6, 6, 19, 19]                       |[6 -> 3, 19 -> 2]        |
|8  |RDK|[21, 21, 21, 21, 20]                    |[21 -> 4, 20 -> 1]       |
|10 |RDK|[1, 1, 1, 2, 2, 45, 45, 45, 45, 2, 2, 2]|[1 -> 3, 2 -> 5, 45 -> 4]|
|8  |RDJ|[20, 20, 21]                            |[20 -> 2, 21 -> 1]       |
|10 |USW|[1, 2, 2, 2, 2, 2, 2]                   |[1 -> 1, 2 -> 6]         |
+---+---+----------------------------------------+-------------------------+

结果有点不同,因为您的分组数据帧以某种方式由重复的行组成,其中
(a,C)=(10,RDK)
。还要注意,我使用了MapType。获取StructType是不可能的,因为结构必须在给定的列中具有相同的字段,这在本例中是不可能的。

当您从原始的
my\u df
创建列表
all\u class
时,实际上最好在第一个groupby中执行此操作:

from pyspark.sql import Window
from pyspark.sql import functions as F

df1 = df.withColumn("cnt", F.count("*").over(Window.partitionBy("A", "C", "Class"))) \
    .groupBy("A", "C") \
    .agg(
    F.map_from_entries(
        F.collect_set(F.struct(F.col("Class"), F.col("cnt")))
    ).alias("Distribution"),
    F.collect_list("Class").alias("all_classes"),
)

df1.show(truncate=False)

#+---+---+-------------------------+----------------------------------------+
#|A  |C  |Distribution             |all_classes                             |
#+---+---+-------------------------+----------------------------------------+
#|7  |SSW|[6 -> 3, 19 -> 2]        |[19, 19, 6, 6, 6]                       |
#|8  |RDK|[20 -> 1, 21 -> 4]       |[20, 21, 21, 21, 21]                    |
#|10 |RDK|[2 -> 5, 1 -> 3, 45 -> 4]|[2, 2, 2, 2, 2, 1, 1, 1, 45, 45, 45, 45]|
#|8  |RDJ|[20 -> 2, 21 -> 1]       |[21, 20, 20]                            |
#|10 |USW|[2 -> 6, 1 -> 1]         |[1, 2, 2, 2, 2, 2, 2]                   |
#+---+---+-------------------------+----------------------------------------+
在这里,我们使用一个窗口计算每个类的出现次数,然后按
a
C
分组以创建
所有\u类
,就像您已经做的那样,但也从count列创建
分布
作为映射列,并使用
map\u from\u entries
函数创建类。如果需要json字符串,可以在map列上使用later
来_json