首页 > 解决方案 > 计算 pyspark 中的滚动总和

问题描述

我有一个数据框,其中包含有关每日销售额和每日点击次数的信息。在我想运行我的分析之前,我想聚合数据。为了让自己更清楚,我将尝试在示例数据框上进行解释

item_id date          Price  Sale   Click   Discount_code     
2       01.03.2019    10       1     10      NULL
2       01.03.2019    8        1     10      Yes
2       02.03.2019    10       0     4       NULL
2       03.03.2019    10       0     6       NULL
2       04.03.2019    6        0     15      NULL 
2       05.03.2019    6        0     14      NULL
2       06.03.2019    5        0     7       NULL 
2       07.03.2019    5        1     11      NULL
2       07.03.2019    5        1     11      NULL
2       08.03.2019    5        0     9       NULL

如果给定日期有两次销售,那么我对该特定日期有两个观察结果。我想通过按 item_id 和价格折叠观察将我的数据框转换为以下数据框:

item_id    Price  CSale  Discount_code Cclicks   firstdate   lastdate  
2           10       1      No             20    01.03.2019 03.03.2019
2           8        1      Yes            10    01.03.2019 01.03.2019
2           6        0      NULL           29    04.03.2019 05.03.2019
2           5        2      NULL           38    06.03.2019 08.03.2019 

其中 CSale 对应于给定价格和给定 item_id 的累积销售额,Cclicks 对应于给定价格和给定 item_id 的累积点击量,firstdate 是给定商品在给定价格下可用的第一个日期,lastdate 是最后一个以给定价格提供给定项目的日期。

标签: pyspark

解决方案


根据问题,OP希望在和的基础上聚合DataFrame 。item_idPrice

# Creating the DataFrames
from pyspark.sql.functions import col, to_date, sum, min, max, first
df = sqlContext.createDataFrame([(2,'01.03.2019',10,1,10,None),(2,'01.03.2019',8,1,10,'Yes'),
                                 (2,'02.03.2019',10,0,4,None),(2,'03.03.2019',10,0,6,None),
                                 (2,'04.03.2019',6,0,15,None),(2,'05.03.2019',6,0,14,None),
                                 (2,'06.03.2019',5,0,7,None),(2,'07.03.2019',5,1,11,None),
                                 (2,'07.03.2019',5,1,11,None),(2,'08.03.2019',5,0,9,None)],
                                ('item_id','date','Price','Sale','Click','Discount_code'))
# Converting string column date to proper date
df = df.withColumn('date',to_date(col('date'),'dd.MM.yyyy'))
df.show()
+-------+----------+-----+----+-----+-------------+
|item_id|      date|Price|Sale|Click|Discount_code|
+-------+----------+-----+----+-----+-------------+
|      2|2019-03-01|   10|   1|   10|         null|
|      2|2019-03-01|    8|   1|   10|          Yes|
|      2|2019-03-02|   10|   0|    4|         null|
|      2|2019-03-03|   10|   0|    6|         null|
|      2|2019-03-04|    6|   0|   15|         null|
|      2|2019-03-05|    6|   0|   14|         null|
|      2|2019-03-06|    5|   0|    7|         null|
|      2|2019-03-07|    5|   1|   11|         null|
|      2|2019-03-07|    5|   1|   11|         null|
|      2|2019-03-08|    5|   0|    9|         null|
+-------+----------+-----+----+-----+-------------+

从下面的 printSchema 中可以看出,数据框的date列是date格式的。

df.printSchema()
root
 |-- item_id: long (nullable = true)
 |-- date: date (nullable = true)
 |-- Price: long (nullable = true)
 |-- Sale: long (nullable = true)
 |-- Click: long (nullable = true)
 |-- Discount_code: string (nullable = true)

最后汇总agg()下面的列。只是一个警告 - 因为Discount_code是一string列,我们也需要聚合它,我们将在分组时取第一个非 Null 值。

df = df.groupBy('item_id','Price').agg(sum('Sale').alias('CSale'),
                                       first('Discount_code',ignorenulls = True).alias('Discount_code'),
                                       sum('Click').alias('Cclicks'),
                                       min('date').alias('firstdate'),
                                       max('date').alias('lastdate'))
df.show()
+-------+-----+-----+-------------+-------+----------+----------+
|item_id|Price|CSale|Discount_code|Cclicks| firstdate|  lastdate|
+-------+-----+-----+-------------+-------+----------+----------+
|      2|    6|    0|         null|     29|2019-03-04|2019-03-05|
|      2|    5|    2|         null|     38|2019-03-06|2019-03-08|
|      2|    8|    1|          Yes|     10|2019-03-01|2019-03-01|
|      2|   10|    1|         null|     20|2019-03-01|2019-03-03|
+-------+-----+-----+-------------+-------+----------+----------+

推荐阅读