如何计算一列的累积和并创建一个新列?

Posted

技术标签:

【中文标题】如何计算一列的累积和并创建一个新列?【英文标题】:How to calculate the cumulative sum of a column and create a new column? 【发布时间】:2021-11-08 00:30:58 【问题描述】:

我有一个 pyspark 数据框:

Location    Month       Brand   Sector  TrueValue   PickoutValue
USA         1/1/2021    brand1  cars1   7418        30000       
USA         2/1/2021    brand1  cars1   1940        2000        
USA         3/1/2021    brand1  cars1   4692        2900        
USA         4/1/2021    brand1  cars1                           
USA         1/1/2021    brand2  cars2   16383104.2  16666667    
USA         2/1/2021    brand2  cars2   26812874.2  16666667    
USA         3/1/2021    brand2  cars2                           
USA         1/1/2021    brand3  cars3   75.6%       70.0%
USA         3/1/2021    brand3  cars3   73.1%       70.0%
USA         2/1/2021    brand3  cars3   77.1%       70.0%

每个品牌的月份值从 2021 年 1 月 1 日到 2021 年 12 月 1 日。我需要创建另一个列,其中包含基于品牌和部门以及按月排序的 TrueValue 列的累积总和。 具有 % 值的行应该是累积总和除以月数。

我预期的数据框是:

Location    Month       Brand   Sector  TrueValue   PickoutValue    TotalSumValue   
USA         1/1/2021    brand1  cars1   7418        30000           7418
USA         2/1/2021    brand1  cars1   1940        2000            9358
USA         3/1/2021    brand1  cars1   4692        2900            14050
USA         4/1/2021    brand1  cars1                               14050
USA         1/1/2021    brand2  cars2   16383104.2  16666667        16383104.2
USA         2/1/2021    brand2  cars2   26812874.2  16666667        43195978.4
USA         3/1/2021    brand2  cars2                               43195978.4
USA         1/1/2021    brand3  cars3   75.6%       70.0%           75.6%
USA         3/1/2021    brand3  cars3   73.1%       70.0%           76.3%
USA         2/1/2021    brand3  cars3   77.1%       70.0%           75.3%

对于具有 % 值的行,这就是我需要计算累积总和的方式按月排序

(75.6 + 0)/1 = 75.6%

(75.6 + 77.1)/2 = 76.3%

(75.6 + 77.1 + 73.1)/3 = 75.3%

我能够生成累积总和,但我没有得到 % 值的累积总和。

这是我的代码块:

df=df.withColumn("month_in_timestamp", to_timestamp(df.Month, 'dd/MM/yyyy'))

windowval = (Window.partitionBy('Brand','Sector').orderBy('Month')
             .rangeBetween(Window.unboundedPreceding, 0))
df1 = df1.withColumn('TotalSumValue', F.sum('TrueValue').over(windowval))

【问题讨论】:

你能解释清楚TotalSumValue是如何计算的吗?\ 这能回答你的问题吗? Pandas groupby cumulative sum TotalSumValue 由 TrueValue 列值的累积和计算得出。例如:对于 1 月,我需要 TotalSumValue 中来自 TrueValue 列的相同值,即 7418。对于下一个值,Jan + Feb 即 7418+1940=9358 等等。 【参考方案1】:

似乎带有 % 的值的计算是累积平均计算。如果是这样,您可以为不包含% 的值应用累积总和,为具有% 的值应用累积平均值(在计算之前先删除百分号)。您可以使用when-otherwise 来应用这两种计算。

import pyspark.sql.functions as F
from pyspark.sql.window import Window

df = df.withColumn("month_in_timestamp", F.to_timestamp(F.col("Month"), 'dd/MM/yyyy'))

# use 'month_in_timestamp' instead of 'month' 
windowval = (Window.partitionBy('Brand','Sector').orderBy('month_in_timestamp')
             .rangeBetween(Window.unboundedPreceding, 0))

df = df.withColumn("TotalSumValue", 
                   F.when(F.col("TrueValue").contains("%"), 
                          F.concat(F.avg(F.expr("replace(TrueValue, '%', '')")).over(windowval).cast("decimal(4,1)"), F.lit("%")))
                    .otherwise(F.sum('TrueValue').over(windowval).cast("decimal(13,1)")))

df.show()

# +--------+--------+------+------+----------+------------+-------------------+-------------+
# |Location|   Month| Brand|Sector| TrueValue|PickoutValue| month_in_timestamp|TotalSumValue|
# +--------+--------+------+------+----------+------------+-------------------+-------------+
# |     USA|1/1/2021|brand1| cars1|      7418|       30000|2021-01-01 00:00:00|       7418.0|
# |     USA|2/1/2021|brand1| cars1|      1940|        2000|2021-01-02 00:00:00|       9358.0|
# |     USA|3/1/2021|brand1| cars1|      4692|        2900|2021-01-03 00:00:00|      14050.0|
# |     USA|4/1/2021|brand1| cars1|      null|        null|2021-01-04 00:00:00|      14050.0|
# |     USA|1/1/2021|brand2| cars2|16383104.2|    16666667|2021-01-01 00:00:00|   16383104.2|
# |     USA|2/1/2021|brand2| cars2|26812874.2|    16666667|2021-01-02 00:00:00|   43195978.4|
# |     USA|3/1/2021|brand2| cars2|      null|        null|2021-01-03 00:00:00|   43195978.4|
# |     USA|1/1/2021|brand3| cars3|     75.6%|       70.0%|2021-01-01 00:00:00|        75.6%|
# |     USA|2/1/2021|brand3| cars3|     77.1%|       70.0%|2021-01-02 00:00:00|        76.4%|
# |     USA|3/1/2021|brand3| cars3|     73.1%|       70.0%|2021-01-03 00:00:00|        75.3%|
# +--------+--------+------+------+----------+------------+-------------------+-------------+

【讨论】:

谢谢!!这有帮助:)

以上是关于如何计算一列的累积和并创建一个新列?的主要内容,如果未能解决你的问题,请参考以下文章

根据与另一列的部分匹配创建新列

Pandas:根据另一列的百分比增长率创建一个新列

为多索引 Panda 数据框创建基于另一列的新列

rollapplyr()仅创建一个新列,而不为.SDcols中的每一列创建多个列

Scala Spark Dataframe 创建一个新列,其中包含另一列的最大先前值和当前值

如何创建一个计算数据框列中 ID 频率的列?