如何多次获取相同答案的值,并且需要在每一列中创建每个值

时间:2019-06-12 12:05:23

标签: pyspark

我有如下数据,想从一列中获取具有相同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          - 

1 个答案:

答案 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]))