我有一个带有基于营业日的DateTimeIndex的pandas数据帧.对于索引中的每个月,我还指定了一个"标记"日.
这是该数据帧的玩具版本:
# a dataframe with business dates as the index
df = pd.DataFrame(list(range(91)), pd.date_range('2015-04-01', '2015-6-30'), columns=['foo']).resample('B').last()
# each month has an single, arbitrary marker day specified
marker_dates = [df.index[12], df.index[33], df.index[57]]
Run Code Online (Sandbox Code Playgroud)
对于索引中的每个月,我需要计算foo该月特定行中行的列的平均值.
我需要两种不同的方式来指定这些切片:
1)每天到第n天.
示例可能是(该月的第2至第4个工作日).所以四月平均为1(apr2),4(apr3)和5(apr 6)= 3.33.可能是33(可能4),34(可能5),35(可能是6)= 34.我不认为指数中没有出现的周末/假日为天.
2)标记日期之前/之后的第n天至标记日期之前/之后的第n天.
示例可以是"从标记日期之前1天到每个月中标记日期之后1天的切片的平均值"例如.4月,标记日期为17Apr.看看该指数,我们想要平均值为apr16,apr17和apr20.
对于示例1,我有一个丑陋的解决方案,在那个月我将切掉那个月的行,然后应用 df_slice.iloc[m:n].mean()
每当我开始用熊猫做迭代的事情时,我总是怀疑我做错了.所以我想有一种更干净,更pythonic /矢量化的方式来制作这个月的结果
对于示例2,我不知道基于多个月的任意日期进行切片平均的好方法.
使用 pandas.tseries.offsets 中的 BDay()
import pandas as pd
from pandas.tseries.offsets import BDay
M=2
N=4
start_date = pd.datetime(2015,4,1)
end_date = pd.datetime(2015,6,30)
df = pd.DataFrame(list(range(91)), pd.date_range('2015-04-01', '2015-6-30'), columns=['foo']).resample('B').last()
# for month starts
marker_dates = pd.date_range(start=start_date, end=end_date, freq='BMS')
# create IntervalIndex
bins = pd.IntervalIndex.from_tuples([ (d + (M-1)*BDay(), d + (N-1)*BDay()) for d in marker_dates ], closed='both')
df.groupby(pd.cut(df.index, bins)).mean()
#[2015-04-02, 2015-04-06] 3.333333
#[2015-05-04, 2015-05-06] 34.000000
#[2015-06-02, 2015-06-04] 63.000000
# any markers
marker_dates = [df.index[12], df.index[33], df.index[57]]
# M Bday before, and N Bday after
bins = pd.IntervalIndex.from_tuples([ (d - M*BDay(), d + N*BDay()) for d in marker_dates ], closed='both')
df.groupby(pd.cut(df.index, bins)).mean()
#[2015-04-15, 2015-04-23] 18.428571
#[2015-05-14, 2015-05-22] 48.000000
#[2015-06-17, 2015-06-25] 81.428571
Run Code Online (Sandbox Code Playgroud)