首页 > 解决方案 > 使用 Numpy datetime64 对象索引/切片 Pandas DataFrame

问题描述

我希望能够弄清楚我是否可以让以下工作(Pandas 0.23.4)。非常感激任何的帮助。

import numpy as np
import pandas as pd

rows = 12
rng = pd.date_range('2011-01', periods=rows, freq='M')

df = pd.DataFrame(np.arange(rows), index=rng)

print(df.loc['2011-01'])
print(df.loc[np.datetime64('2011-01')])

第一个print符合我的预期:显示 2011 年 1 月的所有行。但是,第二个抛出一个,KeyError因为该值不在索引中。我希望它会提供相同的输出,但经过一些测试后,我意识到它正在寻找一个完全匹配的 2011-01-01,它不在 DataFrame 中。我想让第二个工作,以便我可以使用numpy.arangepandas.date_range轻松生成可以循环的日期数组。有人让这个工作吗?(似乎这样有效,但前提是您的日期完全匹配。)

标签: pythonpandasnumpydatetimeindexing

解决方案


使用DatetimeIndex.to_period() & Period.month

import numpy as np
import pandas as pd

rows = 12
rng = pd.date_range('2011-01', periods=rows, freq='M')

df = pd.DataFrame(np.arange(rows), index=rng)

# print(df.loc['2011-01'])
for idx, di in enumerate(df.index.to_period()):
    if di.month == np.datetime64('2011-01').item().month:
        print(f'loc: [{idx}] == {df.index[idx]}')

输出:

# loc: [0] == 2011-01-31 00:00:00

由于您的 df 索引包含月末日期,因此您可以使用此技巧df.loc来获取该行:

>>>> df.loc[df.index == np.datetime64('2011-03', 'D') -1]
            0
2011-02-28  1

>>>> df.loc[df.index == np.datetime64('2011-04', 'D') -1]
            0
2011-03-31  2

>>>> df[df.index == np.datetime64('2011-12', 'D') -1]
             0
2011-11-30  10

# use 2012 January 1st minus one day to get 2011 Dec 31st
>>>> df[df.index == np.datetime64('2012-01', 'D') -1]
             0
2011-12-31  11

推荐阅读