计算从列表 pyspark 引用的列的乘积
Calculate product of columns referenced from a list pyspark
我有一个循环生成几个 table 因子的输出并将列名存储在列表中:
| id | f_1a | f_2a |
|:---|:----:|:-----|
|1 |1.2 |0.95 |
|2 |0.7 |0.87 |
|3 |1.2 |1.4 |
col_lst = ['f1_a','f2_a']
| id | f_1b | f_2b | f_3b |
|:---|:----:|:-----|:-----|
|1 |1.6 |1.2 | 0.98 |
|2 |0.9 |0.65 | 1.7 |
|3 |1.1 |1.33 | 1.4 |
col_lst = ['f1_b','f2_b','f_3b']
我很难用 Pyspark 找出一个代码,它允许我创建一个新列,其中包含每个 table 列出的列的乘积,这样:
| id | f_1a | f_2a | f_a |
|:---|:----:|:-----|:----|
|1 |1.2 |0.95 |1.14 |
|2 |0.7 |0.87 |0.61 |
|3 |1.2 |1.4 |1.68 |
| id | f_1b | f_2b | f_3b | f_b |
|:---|:----:|:-----|:-----|:-----|
|1 |1.6 |1.2 | 0.98 | 1.88 |
|2 |0.9 |0.65 | 1.7 | 1 |
|3 |1.1 |1.33 | 1.4 | 2.05 |
如有任何帮助,我们将不胜感激
使用 reduce 应用一致函数,按行乘以列值。
df=spark.createDataFrame([(1 ,1.6 ,1.2 , 0.98) ,
(2 ,0.9 ,0.65 , 1.7 ) ,
(3 ,1.1 ,1.33 , 1.4) ] ,
('id' , 'f_1b' , 'f_2b' , 'f_3b' ))
df.show()
解决方案
df.withColumn('f_b', reduce(lambda a,b: round(a*b,2),[F.col(c) for c in df.drop('id').columns])).show()
结果
+---+----+----+----+----+
| id|f_1b|f_2b|f_3b| f_b|
+---+----+----+----+----+
| 1| 1.6| 1.2|0.98|1.88|
| 2| 0.9|0.65| 1.7| 1.0|
| 3| 1.1|1.33| 1.4|2.04|
+---+----+----+----+----+
这是使用表达式的另一种方式:
首先创建你的col_list
col_lst = ['f_1b','f_2b','f_3b']
或者
col_lst = [col for col in df.columns if col!='id']
然后:
from pyspark.sql import functions as F
df.withColumn("fb",F.round(F.expr("*".join(col_lst)),2)).show()
+---+----+----+----+----+
| id|f_1b|f_2b|f_3b| fb|
+---+----+----+----+----+
| 1| 1.6| 1.2|0.98|1.88|
| 2| 0.9|0.65| 1.7|0.99|
| 3| 1.1|1.33| 1.4|2.05|
+---+----+----+----+----+
我有一个循环生成几个 table 因子的输出并将列名存储在列表中:
| id | f_1a | f_2a |
|:---|:----:|:-----|
|1 |1.2 |0.95 |
|2 |0.7 |0.87 |
|3 |1.2 |1.4 |
col_lst = ['f1_a','f2_a']
| id | f_1b | f_2b | f_3b |
|:---|:----:|:-----|:-----|
|1 |1.6 |1.2 | 0.98 |
|2 |0.9 |0.65 | 1.7 |
|3 |1.1 |1.33 | 1.4 |
col_lst = ['f1_b','f2_b','f_3b']
我很难用 Pyspark 找出一个代码,它允许我创建一个新列,其中包含每个 table 列出的列的乘积,这样:
| id | f_1a | f_2a | f_a |
|:---|:----:|:-----|:----|
|1 |1.2 |0.95 |1.14 |
|2 |0.7 |0.87 |0.61 |
|3 |1.2 |1.4 |1.68 |
| id | f_1b | f_2b | f_3b | f_b |
|:---|:----:|:-----|:-----|:-----|
|1 |1.6 |1.2 | 0.98 | 1.88 |
|2 |0.9 |0.65 | 1.7 | 1 |
|3 |1.1 |1.33 | 1.4 | 2.05 |
如有任何帮助,我们将不胜感激
使用 reduce 应用一致函数,按行乘以列值。
df=spark.createDataFrame([(1 ,1.6 ,1.2 , 0.98) ,
(2 ,0.9 ,0.65 , 1.7 ) ,
(3 ,1.1 ,1.33 , 1.4) ] ,
('id' , 'f_1b' , 'f_2b' , 'f_3b' ))
df.show()
解决方案
df.withColumn('f_b', reduce(lambda a,b: round(a*b,2),[F.col(c) for c in df.drop('id').columns])).show()
结果
+---+----+----+----+----+
| id|f_1b|f_2b|f_3b| f_b|
+---+----+----+----+----+
| 1| 1.6| 1.2|0.98|1.88|
| 2| 0.9|0.65| 1.7| 1.0|
| 3| 1.1|1.33| 1.4|2.04|
+---+----+----+----+----+
这是使用表达式的另一种方式:
首先创建你的col_list
col_lst = ['f_1b','f_2b','f_3b']
或者
col_lst = [col for col in df.columns if col!='id']
然后:
from pyspark.sql import functions as F
df.withColumn("fb",F.round(F.expr("*".join(col_lst)),2)).show()
+---+----+----+----+----+
| id|f_1b|f_2b|f_3b| fb|
+---+----+----+----+----+
| 1| 1.6| 1.2|0.98|1.88|
| 2| 0.9|0.65| 1.7|0.99|
| 3| 1.1|1.33| 1.4|2.05|
+---+----+----+----+----+