繁体   English   中英

在 pyspark 中对列表中的不同数据框列求和的正确方法是什么?

[英]Whats is the correct way to sum different dataframe columns in a list in pyspark?

我想对火花数据框中的不同列求和。

代码

from pyspark.sql import functions as F
cols = ["A.p1","B.p1"]
df = spark.createDataFrame([[1,2],[4,89],[12,60]],schema=cols)

# 1. Works
df = df.withColumn('sum1', sum([df[col] for col in ["`A.p1`","`B.p1`"]]))

#2. Doesnt work
df = df.withColumn('sum1', F.sum([df[col] for col in ["`A.p1`","`B.p1`"]]))

#3. Doesnt work
df = df.withColumn('sum1', sum(df.select(["`A.p1`","`B.p1`"])))

为什么不是方法#2。 &#3。 不工作? 我在 Spark 2.2

因为,

# 1. Works
df = df.withColumn('sum1', sum([df[col] for col in ["`A.p1`","`B.p1`"]]))

在这里,您使用的是 python 内置 sum 函数,它以 iterable 作为输入,所以它可以工作。 https://docs.python.org/2/library/functions.html#sum

#2. Doesnt work
df = df.withColumn('sum1', F.sum([df[col] for col in ["`A.p1`","`B.p1`"]]))

在这里,您使用的是 pyspark sum 函数,该函数将列作为输入,但您试图在行级别获取它。 http://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.functions.sum

#3. Doesnt work
df = df.withColumn('sum1', sum(df.select(["`A.p1`","`B.p1`"])))

在这里, df.select() 返回一个数据帧并尝试对数据帧求和。 在这种情况下,我认为,您必须逐行迭代并对其应用 sum。

TL; DR builtins.sum很好。


按照您的意见

使用原生 python sum() 并没有从 spark 优化中受益。 那么这样做的火花方式是什么

它不是 pypark 功能,因此它不会真正完全从 spark 中受益。

我可以看到您做出了不正确的假设。

让我们分解问题:

[df[col] for col in ["`A.p1`","`B.p1`"]]

创建列表Columns

[Column<b'A.p1'>, Column<b'B.p1'>]

我们称其为iterable

sum通过获取此列表的元素并调用__add__方法 ( + ) 来减少输出。 等价的命令是:

accum = iterable[0]
for element in iterable[1:]:
    accum = accum + element

这给出了Column

Column<b'(A.p1 + B.p1)'>

这与调用相同

df["`A.p1`"] + df["`B.p1`"]

没有触及任何数据,并且在评估时受益于所有 Spark 优化。

将列表中的多列添加到一列中

我尝试了很多方法,以下是我的观察:

  1. PySpark 的sum函数不支持列加法(Pyspark 2.3.1 版)
  2. 内置 python 的sum函数对某些人有效,但对其他人却出错(可能是因为名称冲突)

在您的第三种方法中,表达式(在 python 的sum函数中)返回一个 PySpark DataFrame。

因此,可以使用 PySpark 中的expr函数实现多列的添加,该函数将要计算的表达式作为输入。

from pyspark.sql.functions import expr

cols_list = ['a', 'b', 'c']

# Creating an addition expression using `join`
expression = '+'.join(cols_list)

df = df.withColumn('sum_cols', expr(expression))

这为我们提供了所需的列总和。 我们还可以使用任何其他复杂表达式来获得其他输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM