看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在时间序列数据中,索引经常是时间类型,我们对数据的操作要经常与时间类型索引打交道,本文将介绍如何查询操作时间类型索引。
DatetimeIndex
作为时间索引,同样也支持数据切片:
rng = pd.date_range('1/1/2021', '12/1/2021', freq='BM')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
'''
2021-01-29 0.216985
2021-02-26 -1.019431
2021-03-31 2.239779
2021-04-30 0.844563
2021-05-31 -0.637188
2021-06-30 0.813345
2021-07-30 -0.845968
2021-08-31 0.059855
2021-09-30 0.553753
2021-10-29 0.264783
2021-11-30 0.601772
Freq: BM, dtype: float64
'''
ts[2:4].index
# DatetimeIndex(['2021-03-31', '2021-04-30'], dtype='datetime64[ns]', freq='BM')
ts[::2].index
'''
DatetimeIndex(['2021-01-29', '2021-03-31', '2021-05-31', '2021-07-30',
'2021-09-30', '2021-11-30'],
dtype='datetime64[ns]', freq='2BM')
'''
以下是几种索引的访问方法:
ts['1/29/2021']
# 0.21698543731135092
ts[datetime.datetime(2021, 9, 30):]
'''
2021-09-30 0.553753
2021-10-29 0.264783
2021-11-30 0.601772
Freq: BM, dtype: float64
'''
ts['5/31/2021':'8/31/2021']
'''
2021-05-31 -0.637188
2021-06-30 0.813345
2021-07-30 -0.845968
2021-08-31 0.059855
Freq: BM, dtype: float64
'''
也可以使用部分字符查询一定范围的数据:
ts['2021'] # 查询整个2021年的
ts['2021-6'] # 查询 2021年6月的
ts['2021-6':'2021-10'] # 6月到10月的
dft['2013-1':'2013-2-28 00:00:00'] # 精确时间
dft['2013-1-15':'2013-1-15 12:30:00']
dft2.loc['2013-01-05']
# 索引选择器
idx = pd.IndexSlice
dft2.loc[idx[:, '2013-01-05'], :]
# 带时区,原数据时区可能不是这个
df['2019-01-01 12:00:00+04:00':'2019-01-01 13:00:00+04:00']
在之前的例子中我们看到频率有工作日的,有自然日的,但它们都是以日为单位的,所以日就是他们有的相同的分辨率,也就是最小粒度。可以使用 x.resolution
查看频率的分辨率。
series_minute = pd.Series([1, 2, 3],
pd.DatetimeIndex(['2011-12-31 23:59:00',
'2012-01-01 00:00:00',
'2012-01-01 00:02:00']))
series_minute.index.resolution
# 'minute'
# 按小时取出
series_minute['2011-12-31 23']
'''
2011-12-31 23:59:00 1
dtype: int64
'''
series_minute['2011-12-31 23:59']
# 1
series_minute['2011-12-31 23:59:00']
# 1
另一个例子:
series_second = pd.Series([1, 2, 3],
pd.DatetimeIndex(['2011-12-31 23:59:59',
'2012-01-01 00:00:00',
'2012-01-01 00:00:01']))
# 最小粒度为秒
series_second.index.resolution
# 'second'
series_second['2011-12-31 23:59']
'''
2011-12-31 23:59:59 1
dtype: int64
'''
df.truncate()
作为一个专门对索引的截取工具,可以很好地应用在时序索引上:
rng2 = pd.date_range('2011-01-01', '2012-01-01', freq='W')
ts2 = pd.Series(np.random.randn(len(rng2)), index=rng2)
ts2.truncate(before='2011-11', after='2011-12')
'''
2011-11-06 0.437823
2011-11-13 -0.293083
2011-11-20 -0.059881
2011-11-27 1.252450
Freq: W-SUN, dtype: float64
'''
# 对比以上操作的不同
ts2['2011-11':'2011-12']
'''
2011-11-06 0.437823
2011-11-13 -0.293083
2011-11-20 -0.059881
2011-11-27 1.252450
2011-12-04 0.046611
2011-12-11 0.059478
2011-12-18 -0.286539
2011-12-25 0.841669
Freq: W-SUN, dtype: float64
'''
# 也可以通过自然索引来取
ts2[[0, 2, 6]].index
其他类型数据的使用例子:
df = pd.DataFrame({'A': ['a', 'b', 'c', 'd', 'e'],
'B': ['f', 'g', 'h', 'i', 'j'],
'C': ['k', 'l', 'm', 'n', 'o']},
index=[1, 2, 3, 4, 5])
df
'''
A B C
1 a f k
2 b g l
3 c h m
4 d i n
5 e j o
'''
df.truncate(before=2, after=4)
'''
A B C
2 b g l
3 c h m
4 d i n
'''
# 按列取
df.truncate(before="A", after="B", axis="columns")
'''
A B
1 a f
2 b g
3 c h
4 d i
5 e j
'''
df['A'].truncate(before=2, after=4)
'''
2 b
3 c
4 d
Name: A, dtype: object
'''
截取时间的例子:
dates = pd.date_range('2016-01-01', '2016-02-01', freq='s')
df = pd.DataFrame(index=dates, data={'A': 1})
df.tail()
'''
A
2016-01-31 23:59:56 1
2016-01-31 23:59:57 1
2016-01-31 23:59:58 1
2016-01-31 23:59:59 1
2016-02-01 00:00:00 1
'''
df.truncate(before=pd.Timestamp('2016-01-05'),
after=pd.Timestamp('2016-01-10')).tail()
'''
A
2016-01-09 23:59:56 1
2016-01-09 23:59:57 1
2016-01-09 23:59:58 1
2016-01-09 23:59:59 1
2016-01-10 00:00:00 1
'''
df.truncate('2016-01-05', '2016-01-10').tail()
'''
A
2016-01-09 23:59:56 1
2016-01-09 23:59:57 1
2016-01-09 23:59:58 1
2016-01-09 23:59:59 1
2016-01-10 00:00:00 1
'''
df.loc['2016-01-05':'2016-01-10', :].tail()
'''
A
2016-01-10 23:59:55 1
2016-01-10 23:59:56 1
2016-01-10 23:59:57 1
2016-01-10 23:59:58 1
2016-01-10 23:59:59 1
'''
更新时间:2022-04-04 10:20:51 标签:pandas 索引 时间