核心问题:我有一个有限的月序列,可以根据初始日期具有任意启动日期,例如一个"月"可能定义为1月4日至2月3日,依此类推。我有很多标记的时间序列数据,我想在本月的垃圾箱中投入。无论起步日期如何,几个月的顺序都是给定的。如果序列在2018-8-17开始,则每个后一个月必须从17日开始。
示例数据
在这些开始日期定义的几个月序列中:
DatetimeIndex(['2012-02-15', '2012-03-15', '2012-04-15', '2012-05-15',
'2012-06-15', '2012-07-15', '2012-08-15', '2012-09-15',
'2012-10-15', '2012-11-15', '2012-12-15', '2013-01-15'],
dtype='datetime64[ns]', freq='<DateOffset: kwds={'months': 1}>')
和一个看起来像:
的数据集pd.DataFrame([
[date(2012, 3, 17), 10, 'A'],
[date(2012, 4, 2), 10, 'A'],
[date(2012, 4, 17), 10, 'A'],
],
columns=['date', 'value', 'label'],
)
应合并或集合此数据框中的值以匹配定义的月份,例如导致
之类的东西[
[date(2012, 3, 15), 20, 'A'],
[date(2012, 4, 15), 10, 'A']
]
尽管在dataframe中!
为什么不按月重新组合或使用一天的偏移量?
值得注意的是,这个月范围是基于一个月的偏移(例如relativedelta(months=1)
,因此,如果第一个月开始于5月31日,下个月将于6月30日开始,并且1月31日之后的一个月将于2月28日开始。结果是,使用一天的偏移是无助的。我还没有弄清楚是否有一种基于这个月份定义的方法。
可能有几种方法可以解决此问题。我使用单独的启动和结束日期为主要日期序列创建了一个索引,在SQL中可以连接使用比较,但不幸的是,在Pandas中看不到[尚未看到吗?]。
我认为您需要pd.merge_asof
:
import pandas as pd
import datetime
dateidx = pd.DatetimeIndex(['2012-02-15', '2012-03-15', '2012-04-15', '2012-05-15',
'2012-06-15', '2012-07-15', '2012-08-15', '2012-09-15',
'2012-10-15', '2012-11-15', '2012-12-15', '2013-01-15'])
df_time = pd.DataFrame(index=dateidx)
df_time = df_time.reset_index()
df_values = pd.DataFrame([
[datetime.date(2012, 3, 17), 10, 'A'],
[datetime.date(2012, 4, 2), 10, 'A'],
[datetime.date(2012, 4, 17), 10, 'A'],
],
columns=['date', 'value', 'label'],
)
df_values['date'] = pd.to_datetime(df_values.date)
合并和groupby:
df_merged = pd.merge_asof(df_values, df_time, left_on='date', right_on='index')
df_merged.groupby(['index','label'], as_index=False)['value'].sum()
输出:
index label value
0 2012-03-15 A 20
1 2012-04-15 A 10
您可以将范围作为具有该月末末日边界的DateTimeIndex。
rng = pd.date_range('1/31/2012', periods=120, freq='M')
然后RNG为
DatetimeIndex(['2012-01-31', '2012-02-29', '2012-03-31', '2012-04-30', '2012-05-31', '2012-06-30', '2012-07-31', '2012-08-31', '2012-09-
30', '2012-10-31', '2012-11-30','2012-12-31', '2013-01-31', '2013-02-28', '2013-03-31', '2013-04-30', '2013-05-31', '2013-06-30', '2013-07-31', '2013-08-
31', '2013-09-30', '2013-10-31',...
关键点是找到一个月的31天,并与该日期一起去。