【问题标题】:Spark dataframe operation on list returns [Ljava.lang.Object;@]列表上的 Spark 数据帧操作返回 [Ljava.lang.Object;@]
【发布时间】:2018-08-01 08:52:08
【问题描述】:

我有一个 pyspark 数据框,我在其中分组数据以使用 collect_list 列出。

from pyspark.sql.functions import udf, collect_list
from itertools import combinations, chain

#Create Dataframe
df = spark.createDataFrame( [(1,'a'), (1,'b'), (2,'c')] , ["id", "colA"])   

df.show()
>>>
+---+----+
| id|colA|
+---+----+
|  1|   a|
|  1|   b|
|  2|   c|
+---+----+

#Group by and collect to list
df = df.groupBy(df.id).agg(collect_list("colA").alias("colAlist"))

df.show()
>>>
+---+--------+
| id|colAList|
+---+--------+
|  1|  [a, b]|
|  2|     [c]|
+---+--------+

然后我使用一个函数将列表元素的所有组合查找到一个新列表中

allsubsets = lambda l: list(chain(*[combinations(l , n) for n in range(1,len(l)+1)]))
df = df.withColumn('colAsubsets',udf(allsubsets)(df['colAList']))

所以我会期待像

这样的东西
+---+--------------------+
| id| colAsubsets        |
+---+--------------------+
|  1|  [[a], [b], [a,b]] |
|  2|  [[b]]             |
+---+--------------------+

但我明白了:

df.show()
>>>
 +---+--------+-----------------------------------------------------------------------------------------+
|id |colAList|colAsubsets                                                                              |
+---+--------+-----------------------------------------------------------------------------------------+
|1  |[a, b]  |[[Ljava.lang.Object;@75e2d657, [Ljava.lang.Object;@7f662637, [Ljava.lang.Object;@b572639]|
|2  |[c]     |[[Ljava.lang.Object;@26f67148]                                                           |
+---+--------+-----------------------------------------------------------------------------------------+

有什么想法吗?然后也许如何将列表展平为不同的行?

【问题讨论】:

    标签: apache-spark dataframe pyspark user-defined-functions


    【解决方案1】:

    你需要做的就是从chaincombinations创建的对象中以扁平化的方式提取元素

    变化很大

    allsubsets = lambda l: list(chain(*[combinations(l , n) for n in range(1,len(l)+1)]))
    

    到下面

    allsubsets = lambda l: [[z for z in y] for y in chain(*[combinations(l , n) for n in range(1,len(l)+1)])]
    

    应该给你

    +---+---------+------------------+
    |id |colA_list|colAsubsets       |
    +---+---------+------------------+
    |1  |[a, b]   |[[a], [b], [a, b]]|
    |2  |[c]      |[[c]]             |
    +---+---------+------------------+
    

    希望回答对你有帮助

    【讨论】:

    • 这很有帮助。谢谢
    【解决方案2】:

    改进@RameshMaharjan 的答案,以便将列表展平为不同的行:

    你必须对数组使用explode。您必须先指定 udf 的类型,以免它返回 StringType。

    from pyspark.sql.functions import explode
    from pyspark.sql.types import ArrayType, StringType
    
    allsubsets = lambda l: [[z for z in y] for y in chain(*[combinations(l , n) for n in range(1,len(l)+1)])]
    df = df.withColumn('colAsubsets', udf(allsubsets, ArrayType(ArrayType(StringType())))(df['colAList']))
    df = df.select('id', explode('colAsubsets'))
    

    结果:

    +---+------+
    | id|   col|
    +---+------+
    |  1|   [a]|
    |  1|   [b]|
    |  1|[a, b]|
    |  2|   [c]|
    +---+------+
    

    【讨论】:

    • 感谢您的下一步
    猜你喜欢
    • 2018-04-17
    • 1970-01-01
    • 2016-03-18
    • 2018-09-17
    • 2023-04-07
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多