Ma question est similaire à ce fil: Partitionnement par plusieurs colonnes dans Spark SQL
mais je travaille dans Pyspark plutôt que Scala et je veux passer ma liste de colonnes comme une liste. Je veux faire quelque chose comme ceci:
column_list = ["col1","col2"]
win_spec = Window.partitionBy(column_list)
Je peux faire fonctionner les éléments suivants:
win_spec = Window.partitionBy(col("col1"))
Cela fonctionne également:
col_name = "col1"
win_spec = Window.partitionBy(col(col_name))
Et cela fonctionne aussi:
win_spec = Window.partitionBy([col("col1"), col("col2")])
Convertissez les noms de colonne en expressions de colonne avec une compréhension de liste [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])
Votre première tentative devrait fonctionner.
Prenons l'exemple suivant:
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|
#+----+------+-----+
Supposons que vous vouliez calculer une fraction de la somme pour chaque ligne, en les regroupant par les deux premières colonnes:
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|
#+----+------+--------+