首页 > 解决方案 > 如何选择具有日期时间索引和位置的两组年份?

问题描述

我目前正在处理数十万行及更多行的数据框,并带有由日期时间值创建的索引。

您可以使用以下代码创建我的数据框的微样本:

import pandas as pd
import numpy as np

dates = pd.date_range(start='1/1/2015', end='1/1/2020', freq='H')
df = pd.DataFrame(dates, columns=['Date'])
df['Value'] = np.random.randint(0,1000, len(dates))
df.set_index('Date', inplace=True)

我想选择所有 '2015' 和 2018' 年份,或 '2015-01' 和 '2015-06'。我知道如何在两个值之间用SliceIndex. 我知道如何获得一整年,但我不知道如何获得整整两年loc

df['2015'] # it works
df[(slice('2015', '2016')] # or df['2015':'2016']

# but
df[['2015', '2016']] # it does not work.

事实上,我有一个多重索引。要构建一个示例:

df1 = df.copy()
df['lvl0'] = ['a']*len(df)
df1['lvl0'] = ['b']*len(df)
mlti_df = pd.concat([df, df1]).reset_index().set_index(['lvl0', 'Date'])

mlti_df[(slice(None), ['2015', '2016'])] # <= does not work

是否可以通过这种方式获得行?我昨天在几个小时内寻找没有找到答案。

标签: pythonpandasdatetimeslicemulti-index

解决方案


首先partial string indexing只使用一年,而不是年份列表。

我认为您需要Index.isin提取年份DatetimeIndex.year并过滤boolean indexing

df1 = df[df.index.year.isin([2015, 2016])]
print (df1)
                     Value
Date                      
2015-01-01 00:00:00    858
2015-01-01 01:00:00    807
2015-01-01 02:00:00    895
2015-01-01 03:00:00    159
2015-01-01 04:00:00    176
                   ...
2016-12-31 19:00:00    888
2016-12-31 20:00:00    162
2016-12-31 21:00:00    207
2016-12-31 22:00:00    545
2016-12-31 23:00:00     49

[17544 rows x 1 columns]

对于MultiIndex解决方案是类似的,只需添加MultiIndex.get_level_values

df2 = mlti_df[mlti_df.index.get_level_values('Date').year.isin([2015, 2016])]
print (df2)
                          Value
lvl0 Date                      
a    2015-01-01 00:00:00    626
     2015-01-01 01:00:00    941
     2015-01-01 02:00:00    405
     2015-01-01 03:00:00    249
     2015-01-01 04:00:00    320
                        ...
b    2016-12-31 19:00:00    752
     2016-12-31 20:00:00    829
     2016-12-31 21:00:00    843
     2016-12-31 22:00:00    306
     2016-12-31 23:00:00     96

[35088 rows x 1 columns]

推荐阅读