在pySpark中进行列明智的最有效方法

时间:2018-07-26 19:11:57

标签: python apache-spark pyspark apache-spark-sql

我在Spark中有一个巨大的DataFrame,看起来像这样(事实上,它有更多的Value#列):

Group     Type  Value#1  Value#2  Value#3
   G1  Revenue       11       22       33
   G2  Revenue       12       23       34
   G3  Revenue       13       24       35
   G4  Revenue       14       25       36
   G5  Revenue       15       26       37
   G1    Costs        1        1        1
   G2    Costs        2        2        2
   G3    Costs        3        3        3
   G4    Costs        4        4        4
   G5    Costs        5        5        5

同样,实际数据框包含120个Value#列。

我需要的是对“行”中的每个“组”类型和“列”中的“值#”计算“收入-成本”。

输出应类似于下一个:

Group    Type  Value#1  Value#2  Value#3
   G1  Profit       10       11       22
   G2  Profit       10       11       22
   G3  Profit       10       11       22
   G4  Profit       10       11       22
   G5  Profit       10       11       22

P.S。我正在使用来自Python的Spark 2.1。

谢谢!

1 个答案:

答案 0 :(得分:1)

只需根据Type列将DataFrame分为两个即可。然后将两个过滤后的DataFrames加入并进行减法:

import pyspark.sql.functions as f

value_columns = [c for c in df.columns if c not in {'Group', 'Type'}]
df.where("Type = 'Revenue'").alias("rev")\
    .join(df.where("Type = 'Costs'").alias('cost'), on=["Group"])\
    .select(
        "Group",
        f.lit("Profit").alias("Type"),
        *[(f.col("rev."+c)-f.col("cost."+c)).alias(c) for c in value_columns]
    )\
    .show()
#+-----+------+-------+-------+-------+
#|Group|  Type|Value#1|Value#2|Value#3|
#+-----+------+-------+-------+-------+
#|   G2|Profit|     10|     21|     32|
#|   G3|Profit|     10|     21|     32|
#|   G4|Profit|     10|     21|     32|
#|   G5|Profit|     10|     21|     32|
#|   G1|Profit|     10|     21|     32|
#+-----+------+-------+-------+-------+