Pandas 时间序列重新采样,分箱似乎关闭

fil*_*ppo 6 python time-series resampling pandas

当我注意到这种奇怪的分箱时,我正在用我认为知道的有关大熊猫的一些东西回答另一个问题,即时间序列重采样。

假设我有一个包含每日日期范围索引的数据框和一个我想要重新采样和求和的列。

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
Run Code Online (Sandbox Code Playgroud)

现在我重新采样一个月,一切看起来都很好:

>>>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
Run Code Online (Sandbox Code Playgroud)

如果我尝试在更多个月内重新采样,尽管分箱开始出现问题。这一点尤其明显6M

df.resample("6M").sum()                                                           
            sales
2018-01-31   1507
2018-07-31   8393
2019-01-31   7283
Run Code Online (Sandbox Code Playgroud)

第一个 bin 跨越一个多月,最后一个 bin 跨度为一个月。也许我必须设置closed="left"以获得适当的限制:

df.resample("6M", closed="left").sum()                                            
            sales
2018-06-30   8090
2018-12-31   9054
2019-06-30     39
Run Code Online (Sandbox Code Playgroud)

现在我在 2019 年有一个额外的垃圾箱,里面有 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
Run Code Online (Sandbox Code Playgroud)

请注意,这里也有一些关于 6 月 30 日数据发生了什么的疑问,它是像我期望的那样进入第一个垃圾箱还是第二个?我的意思是最后一个垃圾箱很明显,但同样的情况可能发生在所有垃圾箱中。

ayo*_*rgo 5

M偏移别名时间意味着月底频率。您需要的是6MS哪个是月份开始频率的别名:

df.resample('6MS').sum()
Run Code Online (Sandbox Code Playgroud)

导致

            sales
2018-01-01   8130
2018-07-01   9563
2019-01-01      0
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)