【发布时间】:2019-06-24 14:45:57
【问题描述】:
在 Spark 环境中混合 python map 和 lambda 函数时遇到问题。
给定 df1,我的源数据框:
Animals | Food | Home
----------------------------------
Monkey | Banana | Jungle
Dog | Meat | Garden
Cat | Fish | House
Elephant | Banana | Jungle
Lion | Meat | Desert
我想创建另一个数据框 df2。它将包含两列,每列 df1 一行(在我的示例中为 3)。 第一列将包含 df1 列的名称。第二列将包含出现次数最多的元素数组(在下面的示例中为 n=3)和计数。
Column | Content
-----------------------------------------------------------
Animals | [("Cat", 1), ("Dog", 1), ("Elephant", 1)]
Food | [("Banana", 2), ("Meat", 2), ("Fish", 1)]
Home | [("Jungle", 2), ("Desert", 1), ("Garden", 1)]
我尝试使用 python 列表、映射和 lambda 函数来实现,但与 PySpark 函数发生冲突:
def transform(df1):
# Number of entry to keep per row
n = 3
# Add a column for the count of occurence
df1 = df1.withColumn("future_occurences", F.lit(1))
df2 = df1.withColumn("Content",
F.array(
F.create_map(
lambda x: (x,
[
str(row[x]) for row in df1.groupBy(x).agg(
F.sum("future_occurences").alias("occurences")
).orderBy(
F.desc("occurences")
).select(x).limit(n).collect()
]
), df1.columns
)
)
)
return df2
错误是:
TypeError: Invalid argument, not a string or column: <function <lambda> at 0x7fc844430410> of type <type 'function'>. For column literals, use 'lit', 'array', 'struct' or 'create_map' function.
知道怎么解决吗?
非常感谢!
【问题讨论】:
-
这可以做到,但这并不是 spark 设计的真正问题类型。您可以独立处理每一列并
union结果。你如何断绝关系?为什么是Cat、Dog、Elephant,而其他两个动物的计数也是1? -
@PentaKill 我更喜欢发布我的代码来说明我面临的问题。我不明白你为什么说它没用。
-
@pault 感谢您的评论。我是新手,所以我仍然需要学习。是的,我想我可以独立处理列,但我不确定这是最好的解决方案。我打破了字母顺序的联系。这就是我没有展示狮子和猴子的原因。
标签: python pandas apache-spark lambda pyspark