当我注意到这种奇怪的分档时,我在这里回答了另一个我想知道的关于熊猫的问题,即时间序列重采样。
假设我有一个数据框,其中包含每日日期范围索引和一列,我想对其重新采样并求和。
index = pd.date_range(start="1/1/2018", end="31/12/2018")
df = pd.DataFrame(np.random.randint(100, size=len(index)),
columns=["sales"], index=index)
>>> df.head()
sales
2018-01-01 66
2018-01-02 18
2018-01-03 45
2018-01-04 92
2018-01-05 76
现在我可以按一个月重新采样,一切看起来都很好:
>>>df.resample("1M").sum()
sales
2018-01-31 1507
2018-02-28 1186
2018-03-31 1382
[...]
2018-11-30 1342
2018-12-31 1337
如果我想再分几个月采样,尽管分箱开始显得有些困难。 6M
df.resample("6M").sum()
sales
2018-01-31 1507
2018-07-31 8393
2019-01-31 7283
第一个垃圾箱跨越一个多月,最后一个垃圾箱到未来一个月。也许我必须设置closed="left"
才能获得适当的限制:
df.resample("6M", closed="left").sum()
sales
2018-06-30 8090
2018-12-31 9054
2019-06-30 39
现在我在2019年会有一个额外的bin,其中包含2018-12-31的数据...
这工作正常吗?我错过了应该设置的任何选项吗?
编辑:这是我希望以六个月为间隔重采样一年的输出,第一个间隔从1月1日到6月30日,第二个间隔从7月1日到12月31日。
df.resample("6M", closed="left").sum()
sales
2018-06-30 8090
2018-12-31 9093 # 9054 + 39
请注意,对于6月30日的数据还存在一些疑问,它是否像我期望的那样进入第一个分类箱或第二个分类箱?我的意思是最后一个垃圾箱很明显,但所有垃圾箱中可能都发生了同样的事情。
答案 0 :(得分:1)
添加np.random.seed(365)
来检查我们的两个输出。
print(df.resample("6M", kind='period').sum())
sales
2018-01 8794
2018-07 9033
这项工作对您有用吗?
答案 1 :(得分:1)
M
时间偏移别名表示month end frequency。
您需要的是6MS
,它是月份开始频率的别名:
df.resample('6MS').sum()
导致
sales
2018-01-01 8130
2018-07-01 9563
2019-01-01 0
df.groupby(pd.Grouper(freq='6MS')).sum()
也可以互换使用。
为更加清晰起见,您可以直接比较范围:
>>> pd.date_range('2018-01-01', '2018-12-31', freq='6M')
DatetimeIndex(['2018-01-31', '2018-07-31'], dtype='datetime64[ns]', freq='6M')
>>> pd.date_range('2018-01-01', '2018-12-31', freq='6MS')
DatetimeIndex(['2018-01-01', '2018-07-01'], dtype='datetime64[ns]', freq='6MS')