Вы можете использовать pivot
после groupBy
, но сначала вы можете создать столбец с именем будущего столбца, используя row_number
дляполучить монотонное число для каждого идентификатора в течение Window
.Вот один из способов:
import pyspark.sql.functions as F
from pyspark.sql.window import Window
# create the window on ID and as you need orderBy after,
# you can use a constant to keep the original order do F.lit(1)
w = Window.partitionBy('ID').orderBy(F.lit(1))
# create the column with future columns name to pivot on
pv_df = (df.withColumn('pv', F.concat(F.lit('Brandid_'), F.row_number().over(w).cast('string')))
# groupby the ID and pivot on the created column
.groupBy('ID').pivot('pv')
# in aggregation, you need a function so we use first
.agg(F.first('Brandid')))
и вы получите
pv_df.show()
+---+---------+---------+---------+
| ID|Brandid_1|Brandid_2|Brandid_3|
+---+---------+---------+---------+
| 1| 234| 122| 134|
| 3| 234| 122| null|
| 2| 122| null| null|
+---+---------+---------+---------+
РЕДАКТИРОВАТЬ: чтобы получить столбец в порядке, как запрашивается OP, вы можете использовать lpad
, сначала определите длину для нужного числа:
nb_pad = 3
и замените вышеуказанным способом F.concat(F.lit('Brandid_'), F.row_number().over(w).cast('string'))
на
F.concat(F.lit('Brandid_'), F.lpad(F.row_number().over(w).cast('string'), nb_pad, "0"))
, и если вы не знаете, сколько "0"вам нужно добавить (здесь это было число длины 3 в целом), тогда вы можете получить это значение по
nb_val = len(str(sdf.groupBy('ID').count().select(F.max('count')).collect()[0][0]))