我有一个像下面这样的pyspark.DataFrame
,列为id
,year
和money
。为了简单起见,我只取了一个id
,但可能有多个。
id year money
1 2019 10
1 2018 15
1 2013 13
1 2009 10
1 2015 10
1 2014 11
在每个id
和期间的结果DataFrame
中,我想要过去连续3年的金额总和,不包括记录年份。
例如,对于2019年,我只想取2018年,2017年和2016年的money
之和。因为我们只有2018年,所以总数是15。
另一个例子是2015年,我想取2014年、2013年和2012年的money
之和。因为只有前2个,所以它的总和是24。
生成的DataFrame
如下所示。
id year sum_money
1 2019 15
1 2018 10
1 2015 24
1 2014 13
1 2013 0
1 2009 0
如何才能达到预期的效果。lag
函数是否提供任何这样的功能来只查找我想要的那些年份,或者是否有任何其他方法。
我的方法
我的方法是把历年的累积总和,按年递减排序。然后,对于每个id和年份,找到刚好小于预期窗口的最大年份。
比如说2019年和window = 3
,开始的年份是2016年。因此,数据集中的最小年份,即2015年,是我们必须采取的。对应于2015年,填写该年的cum_sum。
然后在最终结果列中取两个累计和的差值与当年和的值。因此,2019年将是69 - 44 - 10 = 15。其他记录(id
和year
)也是如此。最终数据如下所示。
id year money cum_sum min_year res_sum diff
1 2019 10 69 2015 44 15
1 2018 15 59 2014 34 10
1 2015 10 44 2009 10 24
1 2014 11 34 2009 10 13
1 2013 13 23 2009 10 0
1 2009 10 10 0 0 0
我正在想一个更简单的办法。
1条答案
按热度按时间yc0p9oo01#
在
pyspark
中,我们可以使用rangeBetween
,正如@samkart所指出的:输出:
这个解决方案也让我觉得更加优雅。窗口规格非常灵活和强大。我们不需要创建假条目,也不需要转移等。最初我提供了一个使用
pandas
的解决方案:输出:
编辑:
我认为真实的的问题是如何将其用于具体的季度报告。我用Map解决了这个问题。我们将年份列乘以4,以腾出4个季度的空间:2000被Map到8000,并且8000现在表示Q1,8001表示Q2等。然后我们可以用
rangeBetween
表示12个四分之一。输出: