我有一个大型的pandas数据框,其中包含与之关联的每小时数据。然后我想把它解析成"每月"将每小时数据相加的数据。但是,这些月份不一定是日历月,它们通常在一个月的中间开始,在下个月的中间结束。
我可以建立一个"月"这些日期范围中的每一个都落入并循环通过它,但我认为通过大熊猫有更好的方法来做到这一点。
这是我当前的代码,最后一行引发错误,是问题的症结所在:
dates = pd.Series(pd.date_range('1/1/2015 00:00','3/31/2015 23:45',freq='1H'))
nums = np.random.randint(0,100,dates.count())
df = pd.DataFrame({'date':dates, 'num':nums})
month = pd.DataFrame({'start':['1/4/2015 00:00','1/24/2015 00:00'], 'end':['1/23/2015 23:00','2/23/2015 23:00']})
month['start'] = pd.to_datetime(month['start'])
month['end'] = pd.to_datetime(month['end'])
month['num'] = df['num'][(df['date'] >= month['start']) & (df['date'] <= month['end'])].sum()
我希望输出类似于:
start end num
0 2015-01-04 2015-01-23 23:00:00 33,251
1 2015-01-24 2015-02-23 23:00:00 39,652
但当然,我没有得到它。
答案 0 :(得分:3)
pd.merge_asof
仅适用于pandas 0.19
pd.merge_asof
+ query
+ groupby
pd.merge_asof(df, month, left_on='date', right_on='start') \
.query('date <= end').groupby(['start', 'end']).num.sum().reset_index()
<强> 解释 强>
pd.merge_asof
来自docs
对于左侧DataFrame中的每一行,我们选择右侧DataFrame中的最后一行,其中“on”键小于或等于左侧的键。两个DataFrame必须按键排序。
但这只会考虑start
日期。
query
我在end
处理了query
日期,因为我现在在end
pd.merge_asof
了
groupby
我相信这部分很明显。
答案 1 :(得分:2)
也许你可以转换为一段时间并添加一些天
# create data
dates = pd.Series(pd.date_range('1/1/2015 00:00','3/31/2015 23:45',freq='1H'))
nums = np.random.randint(0,100,dates.count())
df = pd.DataFrame({'date':dates, 'num':nums})
# offset days and then create period
df['periods'] = (df.date + pd.tseries.offsets.Day(23)).dt.to_period('M')]
# group and sum
df.groupby('periods')['num'].sum()
输出
periods
2015-01 10051
2015-02 34229
2015-03 37311
2015-04 26655
然后,您可以将日期转回并创建新列