sparkデータフレーム内の異なる列を合計したい。
コード
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組み込みの合計関数を使用しているため、機能します。 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()はデータフレームを返し、データフレームを合計しようとします。この場合、行ごとに繰り返し、合計を適用する必要があると思います。
TL; DRbuiltins.sum
は問題ありません。
あなたのフォロー コメント :
ネイティブpython sum()を使用しても、spark最適化のメリットはありません。したがって、sparkの方法は何ですか?
これはpypark関数ではないため、spark rightから完全に恩恵を受けることはありません。
あなたが間違った仮定をしていることがわかります。
問題を分解してみましょう:
[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最適化の恩恵を受けています。