PySpark:如何使用窗口函数将固定的日期范围和另一列分组以计算值列的总和?

时间:2019-03-27 16:20:56

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

我有一个由三个列组成的Spark DataFrame:分别为DateItemValue类型的DateStringDouble 。 我想按日期范围(其中每个范围的持续时间为从数据框中的第一个日期开始的7天及以上)和Item进行分组,并计算由日期范围(实际上是周数)和Item定义的每个此类组的Value总和

我怀疑应该在此处将PySpark的Window函数用于日期范围,但无法弄清楚在这种情况下如何实现它们。

1 个答案:

答案 0 :(得分:0)

让我们首先定义此方法-

(a)为行(每个日期)添加week_start_date列

(b)使用分组依据中的week_start_date列(以及“ item”)并计算“值”之和

生成一些测试数据

from pyspark.sql.types import *

schema = StructType([StructField('date', StringType(),True),
                     StructField('item', StringType(),True),
                     StructField('value', DoubleType(),True)
    ]
    )

data = [('2019-01-01','I1',1.1),
        ('2019-01-02','I1',1.1),
        ('2019-01-10','I1',1.1),
        ('2019-01-10','I2',1.1),
        ('2019-01-11','I2',1.1),
        ('2019-01-11','I3',1.1)]

df = spark.createDataFrame(data, schema)

Python函数生成week_start_date

from datetime import datetime, timedelta

def week_start_date(day):
    dt = datetime.strptime(day, '%Y-%m-%d')
    start = dt - timedelta(days=dt.weekday())
    end = start + timedelta(days=6)
    return start.strftime('%Y-%m-%d')

spark.udf.register('week_start_date',week_start_date)

使用函数生成week_start_date,然后按week_start_date和项目分组

 df.selectExpr("week_start_date(date) as start_date","date","item as item","value as value" ).\
        groupBy("start_date","item").\
        agg(sum('value').alias('value_sum')).\
        orderBy("start_date").\
        show()