私の質問はこのスレッドに似ています: Spark SQL)の複数の列によるパーティション化
ScalaではなくPysparkで作業していて、列のリストをリストとして渡したいと思っています。次のようなことをしたいのですが。
column_list = ["col1","col2"]
win_spec = Window.partitionBy(column_list)
以下を機能させることができます:
win_spec = Window.partitionBy(col("col1"))
これも機能します:
col_name = "col1"
win_spec = Window.partitionBy(col(col_name))
そしてこれも機能します:
win_spec = Window.partitionBy([col("col1"), col("col2")])
リスト内包表記[col(x) for x in column_list]
を使用して、列名を列式に変換します。
from pyspark.sql.functions import col
column_list = ["col1","col2"]
win_spec = Window.partitionBy([col(x) for x in column_list])
最初の試みはうまくいくはずです。
次の例について考えてみます。
import pyspark.sql.functions as f
from pyspark.sql import Window
df = sqlCtx.createDataFrame(
[
("a", "Apple", 1),
("a", "orange", 2),
("a", "orange", 3),
("b", "orange", 3),
("b", "orange", 5)
],
["name", "fruit","value"]
)
df.show()
#+----+------+-----+
#|name| fruit|value|
#+----+------+-----+
#| a| Apple| 1|
#| a|orange| 2|
#| a|orange| 3|
#| b|orange| 3|
#| b|orange| 5|
#+----+------+-----+
最初の2列でグループ化して、各行の合計の一部を計算するとします。
cols = ["name", "fruit"]
w = Window.partitionBy(cols)
df.select(cols + [(f.col('value') / f.sum('value').over(w)).alias('fraction')]).show()
#+----+------+--------+
#|name| fruit|fraction|
#+----+------+--------+
#| a| Apple| 1.0|
#| b|orange| 0.375|
#| b|orange| 0.625|
#| a|orange| 0.6|
#| a|orange| 0.4|
#+----+------+--------+