5

我正在生成一个以一系列日期作为索引的空数据框。稍后会将数据添加到数据框中。

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']

我在这里想念什么?为什么第一个切片不返回结果?

4

3 回答 3

14

[]in 的双重行为df[]

  • 当您不使用:inside[]时,其中的值将被视为列。
  • 当您使用:inside时[],其中的值将被视为行。

为什么是双重性质?

因为大多数时候人们想要对行进行切片而不是对列进行切片。

所以他们决定xand yindf[x:y]应该对应于行,

xind[x]x, yindf[[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]

于 2017-01-29T17:55:09.973 回答
4

有区别,因为使用不同的方法:

对于选择一行是必要的loc

df['2017-01-02']

文档 - 部分字符串索引

警告

以下选择将引发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']

这是纯部分字符串索引

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

于 2017-01-29T16:04:12.567 回答
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]:

我们尝试“Test1”:

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 文档指出“以下选择将引发 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
于 2017-01-29T21:30:54.780 回答