如何在pyspark中按字段对每个组的值求和

c0vxltue  于 2021-07-12  发布在  Spark
关注(0)|答案(2)|浏览(344)

我有一个名为“df”的Dataframe,它位于groupby的“accountname”字段中,该列中的每个条目都有一个成本,可以相同,也可以不同,我只需要在不同的时候添加它。这是原始数据框:

accountname |   namespace   |   cost    
account001  |   ns1         |   11      
account001  |   ns1         |   11      
account001  |   ns1         |   11      
account001  |   ns1         |   11      
account001  |   ns2         |   10      
account001  |   ns2         |   10      
account002  |   ns3         |   50      
account002  |   ns3         |   50      
account002  |   ns3         |   50      
account003  |   ns4         |   5

“accountname”字段中唯一具有不同成本的条目是“account001”,我只需要添加11+10一次。我需要得到这样的东西:

accountname |   namespace   |   cost    |   cost_to_pay
account001  |   ns1         |   11      |   21
account001  |   ns1         |   11      |   21
account001  |   ns1         |   11      |   21
account001  |   ns1         |   11      |   21
account001  |   ns2         |   10      |   21
account001  |   ns2         |   10      |   21
account002  |   ns3         |   50      |   50
account002  |   ns3         |   50      |   50
account002  |   ns3         |   50      |   50
account003  |   ns4         |   5       |   5

你知道怎么做吗?提前谢谢。

bcs8qyzn

bcs8qyzn1#

可以使用删除重复项 distinct ,分组依据 accountname 和成本之和,并使用 accountname :

import pyspark.sql.functions as F

df2 = (df.dropDuplicates(['accountname', 'namespace', 'cost'])
         .groupBy('accountname')
         .agg(F.sum('cost').alias('cost_to_pay'))
         .join(df, 'accountname')
         .select('accountname', 'namespace', 'cost', 'cost_to_pay')
      )

df2.show()
+-----------+---------+----+-----------+
|accountname|namespace|cost|cost_to_pay|
+-----------+---------+----+-----------+
| account001|      ns1|  11|         21|
| account001|      ns1|  11|         21|
| account001|      ns1|  11|         21|
| account001|      ns1|  11|         21|
| account001|      ns2|  10|         21|
| account001|      ns2|  10|         21|
| account002|      ns3|  50|         50|
| account002|      ns3|  50|         50|
| account002|      ns3|  50|         50|
| account003|      ns4|   5|          5|
+-----------+---------+----+-----------+
yebdmbv4

yebdmbv42#

你可以用 collect_set Windows上方 accountname 要获得不同的成本值,请使用 aggregate 功能:

from pyspark.sql import functions as F

df1 = df.withColumn(
    "cost_to_pay",
    F.expr("aggregate(collect_set(cost) over(partition by accountname), 0D, (acc, x) -> acc + x)")
)

df1.show()

# +-----------+---------+----+-----------+

# |accountname|namespace|cost|cost_to_pay|

# +-----------+---------+----+-----------+

# | account003|      ns4|   5|          5|

# | account001|      ns1|  11|         21|

# | account001|      ns1|  11|         21|

# | account001|      ns1|  11|         21|

# | account001|      ns1|  11|         21|

# | account001|      ns2|  10|         21|

# | account001|      ns2|  10|         21|

# | account002|      ns3|  50|         50|

# | account002|      ns3|  50|         50|

# | account002|      ns3|  50|         50|

# +-----------+---------+----+-----------+

相关问题