Python 获取从中的最后一个日期开始计算的每年最后一个值

Python 获取从中的最后一个日期开始计算的每年最后一个值,python,pandas,Python,Pandas,在熊猫中,什么是按年份重新采样/分组/等的最佳方式,而不是按日历年计算,而是从数据中的最后一个日期开始计算完整的年份 示例数据集 pd.DataFrame({ 'MyDate': ['2017-02-01', '2017-07-05', '2017-08-26', '2017-09-03', '2018-02-04', '2018-08-03', '2018-08-10', '2018-12-03', '2019-07-13', '2019-08-15'],

在熊猫中,什么是按年份重新采样/分组/等的最佳方式,而不是按日历年计算,而是从数据中的最后一个日期开始计算完整的年份

示例数据集

pd.DataFrame({
  'MyDate': ['2017-02-01', '2017-07-05', '2017-08-26', '2017-09-03', '2018-02-04', 
             '2018-08-03', '2018-08-10', '2018-12-03', '2019-07-13', '2019-08-15'],
  'MyValue': [100, 90, 80, 70, 60, 50, 40, 30, 20, 10]
})
示例结果

pd.DataFrame({
  'MyDate': ['2017-02-01', '2017-07-05', '2017-08-26', '2017-09-03', '2018-02-04', 
             '2018-08-03', '2018-08-10', '2018-12-03', '2019-07-13', '2019-08-15'],
  'MyValue': [100, 90, 80, 70, 60, 50, 40, 30, 20, 10]
})
最后一个日期是2019-08-15,所以我想按最后一个全年2018-08-16-2019-08-15、2017-08-17-2018-08-15等进行分组

以下是每年的最后一次结果:

MyDate  MyValue
0   2017-07-05  90
1   2018-08-10  40
2   2019-08-15  10

一种方法是使用
pd.cut
,指定带有
pd.offset.DateOffset
的箱子以获得日历年间隔

import numpy as np
import pandas as pd

df['MyDate'] = pd.to_datetime(df['MyDate'])

N = int(np.ceil((df.MyDate.max()-df.MyDate.min())/np.timedelta64(1, 'Y')))+1
bins = [df.MyDate.max()-pd.offsets.DateOffset(years=y) for y in range(N)][::-1]

df.groupby(pd.cut(df.MyDate, bins)).last()

#                             MyDate  MyValue
#MyDate                                      
#(2016-08-15, 2017-08-15] 2017-07-05       90
#(2017-08-15, 2018-08-15] 2018-08-10       40
#(2018-08-15, 2019-08-15] 2019-08-15       10

您可以减去上一个值并创建年份组,然后通过以下各项传递到
groupby


首先需要将日期解析为真实的日期对象,如:

df['MyDate'] = pd.to_datetime(df['MyDate'])
下一步,我们可以通过以下方式执行分组:


对于2017年的预期结果,您确定您粘贴了好的一行吗?你不想改成
2017-09-03 70
吗?@BenoitDrogou不,因为2017-09-03(9月3日)已经过了8月15日的截止日期。这个答案是迄今为止表现最慢的(我在本地的其他答案是1秒对40ms),但在relativedelta和attrgetter的有趣使用上,投票率更高@亚历克斯弗里德曼:答案旨在正确定义“年”:。不幸的是,日历不是很容易,因为不是每一年都有相同的年数。但我同意它不是非常快。ALollz在回答中使用的DateOffset确实工作得很快,可能是因为它是熊猫的原生版本。我喜欢它的简单性,但365.25不知何故让我感到痛苦,因为它漂亮的简单性和输出范围的额外好处
df['MyDate'] = pd.to_datetime(df['MyDate'])
>>> from operator import attrgetter
>>> from dateutil.relativedelta import relativedelta
>>> df.groupby(df['MyDate'].apply(relativedelta, dt2=df['MyDate'].max()).apply(attrgetter('years'))).last()
           MyDate  MyValue
MyDate                    
-2     2017-07-05       90
-1     2018-08-10       40
 0     2019-08-15       10