我有如下数据,想从一列中获取具有相同ID的数据,并将每个答案分别放在不同的新列中
actual
ID Brandid
1 234
1 122
1 134
2 122
3 234
3 122
Excpected
ID BRANDID_1 BRANDID_2 BRANDID_3
1 234 122 134
2 122 - -
3 234 122 -
答案 0 :(得分:0)
您可以在pivot
之后使用groupBy
,但是首先可以使用row_number
创建带有将来列名称的列,以获取Window
上每个ID的单数。这是一种方法:
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]))