2017-12-07 1 views
3

スパークデータフレーム内の異なる列を合計します。pysparkのリスト内の異なるデータフレーム列を合計する正しい方法は何ですか?

コード#2に近づくされていないのはなぜ

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`"]))) 

。 &#3。働いていない?あなたは内蔵の入力としてのiterableを取るSUM関数のpythonを使用しているので、それが動作ここ

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

、ので は、私には、Spark 2.2

答えて

2

にしています。 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サム機能を使用しているが、あなたが行レベルでそれを取得しようとしています。ここで 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は()のデータフレームを返し、データフレームを超える合計しようとしています。この場合は、行方向に反復して合計を適用する必要があると思います。

+0

ありがとうございました。ネイティブのpython sum()は、スパークの最適化のメリットがありません。それを行うスパークの方法は何ですか? –

+0

上記のように2つの列だけを使用している場合、df.withColumn( 'sum1'、df ['A.p1''] + df ['' B.p1' '])を直接合計することができます。しかし、多くの列がある場合、UDFを使用することができます。 – Suresh

+0

リストにn個の列を渡して合計します。私の列のリストは、ユーザ入力に基づいて変更されます –

3

TL; DRbuiltins.sumは問題ありません。


あなたcomments後:

()は、スパークの最適化の恩恵を受けていないネイティブのpythonの合計を使用。それは本当に完全にスパーク右の恩恵を受けことができる文句を言わないように、そのないpypark機能

and

それを行うのスパーク道いただきましたので。

誤った前提があることがわかります。

はの問題を分解してみましょう:

[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を与える:

ませデータは触れられていないと評価されたとき、それはすべてのスパークの最適化による利益である

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

を呼び出すのと同じである

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

関連する問題