无法使用日期作为字符串对pandas数据帧(以日期为键)进行切片

时间:2017-01-29 15:52:48

标签: python pandas dataframe datetimeindex

我生成一个空数据框,其中包含一系列日期作为索引。数据将在稍后添加到数据框中。

cbd=pd.date_range(start=pd.datetime(2017,01,02),end=pd.datetime(2017,01,30),period=1)

df = pd.DataFrame(data=None,columns=['Test1','Test2'],index=cbd)

df.head()
           Test1 Test2
2017-01-02   NaN   NaN
2017-01-03   NaN   NaN
2017-01-04   NaN   NaN
2017-01-05   NaN   NaN
2017-01-06   NaN   NaN

一些切片方法似乎不起作用。以下返回KeyError:

df['2017-01-02']

然而,以下任何工作:

df['2017-01-02':'2017-01-02']
df.loc['2017-01-02']

我在这里缺少什么?为什么第一个切片没有返回结果?

3 个答案:

答案 0 :(得分:11)

[]

df[]的双重行为
  • 如果您未在:内使用[],则其中的值将被视为列。
  • 当您在:内使用[]时,其中的值将被视为行。

为什么双重性?

因为大多数时候人们想要切片而不是切片。因此,他们认为x中的ydf[x:y]应与xd[x]x中的行和y对应df[[x,y]]应与列对应。

实施例

df = pd.DataFrame(data = [[1,2,3], [1,2,3], [1,2,3]],
                                 index = ['A','B','C'], columns = ['A','B','C'])
print df

输出:

   A  B  C
A  1  2  3
B  1  2  3
C  1  2  3

现在当你做df['B']时,它可能意味着两件事:

  • 取第二个索引B并给你第二行1 2 3

                    OR
    
  • 取第二列B并为您提供第二列2 2 2

因此,为了解决此冲突并保持明确df['B']将始终意味着您需要列'B',如果没有此列,则会抛出错误。

为什么df['2017-01-02']会失败?

它将搜索列'2017-01-02',因为没有这样的列,所以会抛出错误。

为什么df.loc['2017-01-02']会起作用?

由于.loc[]的语法为df.loc[row,column],如果您愿意,可以省略该列,就像您的情况一样,它只是意味着df.loc[row]

答案 1 :(得分:4)

存在差异,因为使用不同的方法:

如需选择一行loc

  

DF [' 2017年1月2日']

Docs - partial string indexing

  

警告

     

以下选择会引发 KeyError ;否则这种选择方法将与pandas中的其他选择方法不一致(因为这不是切片,也不是解决方案):

dft['2013-1-15 12:30:00']
  

要选择单行,请使用.loc

In [74]: dft.loc['2013-1-15 12:30:00']
Out[74]: 
A    0.193284
Name: 2013-01-15 12:30:00, dtype: float64
df['2017-01-02':'2017-01-02']

这是纯粹的partial string indexing

  

这种类型的切片也适用于带有 DateTimeIndex DataFrame。由于部分字符串选择是标签切片的一种形式,因此将包括端点 。这将包括在包含日期的匹配时间。

答案 2 :(得分:1)

首先,我更新了您的测试数据(仅供参考),因为它返回了一个无效的令牌'错误。请在此处查看更改:

cbd=pd.date_range(start='2017-01-02',end='2017-01-30',period=1)
df = pd.DataFrame(data=None,columns=['Test1','Test2'],index=cbd)

现在看第一行:

In[1]:

df.head(1)

Out[1]:
          Test1 Test2
2017-01-02  NaN NaN

然后尝试初始切片方法会产生此错误:

In[2]:    

df['2017-01-02']

Out[2]:

KeyError: '2017-01-02'

现在使用column名称尝试此操作:

In[3]:    

df.columns

Out[3]:

Index(['Test1', 'Test2'], dtype='object')

In[4]:

我们尝试“测试1':

df['Test1']

从此列获取NaN输出。

Out[4]:

2017-01-02    NaN
2017-01-03    NaN
2017-01-04    NaN
2017-01-05    NaN

因此,您使用的格式旨在用于column名称,除非您使用此格式df['2017-01-02':'2017-01-02']

Pandas docs状态"以下选择将引发KeyError;否则这种选择方法将与pandas中的其他选择方法不一致(因为这不是一个切片,也不是解决方案)"。

因此,正确识别后,DataFrame.loc是一个基于标签的索引器,可以生成您正在寻找的输出:

 In[5]:
df.loc['2017-01-02']

 Out[5]:

Test1    NaN
Test2    NaN
Name: 2017-01-02 00:00:00, dtype: object