带有Numpy datetime64对象的索引/切片熊猫数据框

时间:2018-10-18 22:31:08

标签: python pandas numpy datetime indexing

我希望能够弄清楚是否可以使以下内容起作用(熊猫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年1月1日完全匹配的内容,该内容不在DataFrame中。我希望第二个可以工作,这样我就可以使用numpy.arangepandas.date_range轻松生成我可以循环通过的日期数组。有人让这个工作吗? (看起来像this works,但前提是您的日期完全匹配。)

2 个答案:

答案 0 :(得分:1)

使用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

答案 1 :(得分:1)

您可以编写将np.datetime64转换为与Pandas兼容的字符串的函数:

def stringify(x):
    year = x.astype('datetime64[Y]').astype(int) + 1970
    month = x.astype('datetime64[M]').astype(int) % 12 + 1
    return f'{year}-{month:02}'

a = df.loc['2011-01']
b = df.loc[stringify(np.datetime64('2011-01'))]

assert a.equals(b)