在Pyspark df中将字典键添加为列名,将字典值添加为该列的常量值
我有一本字典x={'colA':20,'colB':30}和一本pyspark df在Pyspark df中将字典键添加为列名,将字典值添加为该列的常量值,pyspark,apache-spark-sql,pyspark-sql,Pyspark,Apache Spark Sql,Pyspark Sql,我有一本字典x={'colA':20,'colB':30}和一本pyspark df ID Value 1 ABC 1 BCD 1 AKB 2 CAB 2 AIK 3 KIB 我希望使用x创建df1,如下所示: ID Value colA colB 1 ABC 20.0 30.0 1 BCD 20.0 30.0 1 AKB 20.0 30.0 2 CAB 20.0 30.0 ... 你知道怎么做吗。 我知道我可以创建这样的常量列 df1
ID Value
1 ABC
1 BCD
1 AKB
2 CAB
2 AIK
3 KIB
我希望使用x创建df1,如下所示:
ID Value colA colB
1 ABC 20.0 30.0
1 BCD 20.0 30.0
1 AKB 20.0 30.0
2 CAB 20.0 30.0
...
你知道怎么做吗。
我知道我可以创建这样的常量列
df1 = df.withColumn('colA', lit(20.0))
df1 = df1.withColumn('colB', lit(30.0))
但不确定从dictionary循环执行该操作的动态过程,如下所示
df1 = df
for key in x:
df1 = df1.withColumn(key, lit(x[key]))
有很多方法可以隐藏循环,但执行过程是相同的。例如,您可以使用选择:
从pyspark.sql.functions导入
df2=df.选择*,*[litval.aliaskey代表键,val代表x.items]
df2.show
+--+---+--+--+
|ID | Value | colB | colA|
+--+---+--+--+
|1 | ABC | 30 | 20|
|1 | BCD | 30 | 20|
|1 | AKB | 30 | 20|
|2 |驾驶室| 30 | 20|
|2 | AIK | 30 | 20|
|3 | KIB | 30 | 20|
+--+---+--+--+
或functools.reduce和with列:
从functools导入reduce
df3=reducelambda-df,key:df.withColumnkey,litx[key],x,df
df3.show
同上
或与:
从pyspark.sql.functions导入结构
df4=df.withColumn'x',struct[litval.aliaskey表示键,val表示x.items]\
.selectID,Value,x*
df4.show
同上
但如果您查看这些方法的执行计划,就会发现它们完全相同:
解释
==实际计划==
*项目[ID44L,值45,30为colB151,20为colA152]
+-扫描现有RDD[ID44L,值45]
解释
==实际计划==
*项目[ID44L,值45,30为colB102,20为colA107]
+-扫描现有RDD[ID44L,值45]
解释
==实际计划==
*项目[ID44L,值45,30为colB120,20为colA121]
+-扫描现有RDD[ID44L,值45]
此外,如果您比较@anil中的循环方法:
df1=df
对于输入x:
df1=df1.withColumnkey,litx[key]
解释
==实际计划==
*项目[ID44L,值45,30为colB127,20为colA132]
+-扫描现有RDD[ID44L,值45]
你会发现这也是一样的。谢谢。有没有办法将所有键应用到一起,一次创建所有列而不经过循环?即使在循环中应用它,spark也只会执行一次,因为它是一个懒惰的计算。。。你不必担心性能。好的。知道了。我也找到了这个解决方案,但我认为它效率低下。这就是为什么我问你。非常感谢你的帮助。我有一个类似的问题,@pault