web-dev-qa-db-fra.com

Partitionnement par plusieurs colonnes dans PySpark avec des colonnes dans une liste

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

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])
9
Psidom

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|
#+----+------+--------+
0
pault