Pandas的asfreq方法使用中漏掉了什么
考虑以下代码:
r = pandas.date_range(datetime(2014,5,26),datetime(2014,6,6))
ts = pandas.Series(np.random.randn(len(r)), index=r)
print(ts.asfreq(pandas.DateOffset(days=5),how='end'))
我觉得我对“how”这个参数的用法理解得不太对。根据上面的代码,我本以为从最后开始,asfreq的结果会每5天返回一次。但我得到的结果是:
2014-05-26 0.456856
2014-05-31 -0.552287
2014-06-05 0.169554
Freq: <DateOffset: kwds={'days': 5}>, dtype: float64
如果我这样做:
print(ts.asfreq(pandas.DateOffset(days=5),how='start'))
结果完全没有变化,还是得到了同样的结果。
然后我看到在pandas.Series.asfreq的文档中提到:
how : {‘start’, ‘end’}, default end
For PeriodIndex only, see PeriodIndex.asfreq
这让我意识到我的问题在于我需要使用DatetimeIndex。
我的问题是,在我的例子中,如何正确调用才能始终返回一个系列,最后一点是2014-05-30,范围的结束日期是2014-06-06,无论我在范围中设置的开始日期是什么?asfreq似乎不适用于降序索引,所以反转索引似乎也不是一个选项……
1 个回答
针对你的问题,这里有几个需要注意的地方:
首先,我不太明白在这里使用 DateOffset 的意义,你可以直接用 "5D" 来替代,这样得到的结果是一样的。
其次,使用 period_range 来生成时间索引会更好。第三点后面会给出一个例子。
最后,似乎你不太明白当使用 "how" 选项时 asfreq 的作用。简单来说,当 asfreq 里的 "freq" 设置为更大的频率(或者更小的时间间隔)时,就会用到 "how" 选项。下面我用一个例子来说明:
import pandas as pd
import numpy as np
rng = pd.period_range('20140526','20140606')
如果我把频率设置为 "start":
print(rng.asfreq('H', how='start'))
结果是:
PeriodIndex(['2014-05-26 00:00', '2014-05-27 00:00', '2014-05-28 00:00',
'2014-05-29 00:00', '2014-05-30 00:00', '2014-05-31 00:00',
'2014-06-01 00:00', '2014-06-02 00:00', '2014-06-03 00:00',
'2014-06-04 00:00', '2014-06-05 00:00', '2014-06-06 00:00'],
dtype='int64', freq='H')
所有的小时都被设置为那一天的 00:00。
但是,如果 "how" 设置为 "end"
print(rng.asfreq('H', how='end'))
结果就变成:
PeriodIndex(['2014-05-26 23:00', '2014-05-27 23:00', '2014-05-28 23:00',
'2014-05-29 23:00', '2014-05-30 23:00', '2014-05-31 23:00',
'2014-06-01 23:00', '2014-06-02 23:00', '2014-06-03 23:00',
'2014-06-04 23:00', '2014-06-05 23:00', '2014-06-06 23:00'],
dtype='int64', freq='H')
所有的小时都被设置为 23:00,也就是说,每一天的最后一个小时的时间戳。
所以这里的重点是:只有当新的频率(小时)大于旧的频率(天)时,"how" 才有用。但在这种情况下,你并不是在对时间序列进行子集或重采样,而是根据新的频率给每个时间点一个新的索引。
至于如何实现你的目标,既然你已经标记了所有重要的时间点,为什么不使用这些时间点来创建一个周期索引呢:
r = pd.period_range('20140530','20140609',freq="5D")
print(r)
PeriodIndex(['2014-05-30', '2014-06-04', '2014-06-09'], dtype='int64', freq='5D')