【问题标题】:Selecting a row of pandas series/dataframe by integer index通过整数索引选择一行熊猫系列/数据框
【发布时间】:2013-04-12 09:00:06
【问题描述】:

我很好奇为什么不支持df[2],而df.ix[2]df[2:3] 都可以工作。

In [26]: df.ix[2]
Out[26]: 
A    1.027680
B    1.514210
C   -1.466963
D   -0.162339
Name: 2000-01-03 00:00:00

In [27]: df[2:3]
Out[27]: 
                  A        B         C         D
2000-01-03  1.02768  1.51421 -1.466963 -0.162339

我希望df[2] 的工作方式与df[2:3] 相同,以符合 Python 索引约定。不支持按单个整数索引行是否有设计原因?

【问题讨论】:

  • df.ix[2] 不起作用 - 至少在 pandas version '0.19.2' 中不起作用
  • 通过索引运算符查看行和列选择之间的区别,[]see this answer below。另外永远不要使用.ix,它已被弃用
  • 不确定是否有帮助,但如果只是为了阅读/查看,可以使用df.values[n] 查看第 n 行。

标签: python pandas dataframe indexing


【解决方案1】:

呼应@HYRY,请参阅 0.11 中的新文档

http://pandas.pydata.org/pandas-docs/stable/indexing.html

这里有新的运算符,.iloc 明确支持整数索引,.loc 明确支持标签索引

例如想象一下这个场景

In [1]: df = pd.DataFrame(np.random.rand(5,2),index=range(0,10,2),columns=list('AB'))

In [2]: df
Out[2]: 
          A         B
0  1.068932 -0.794307
2 -0.470056  1.192211
4 -0.284561  0.756029
6  1.037563 -0.267820
8 -0.538478 -0.800654

In [5]: df.iloc[[2]]
Out[5]: 
          A         B
4 -0.284561  0.756029

In [6]: df.loc[[2]]
Out[6]: 
          A         B
2 -0.470056  1.192211

[] 仅对行进行切片(按标签位置)

【讨论】:

  • 如果您想要第 2 行和第 3 行和第 4 行怎么办?
  • 你可以简单地传递一个索引器列表;文档指向上面
  • 有没有人为这些名字辩护?我发现这些很难记住,因为我不确定为什么 iloc 是行而 loc 是标签。
  • @kilojoules .iloc 按它们在索引中的顺序查找事物(例如.iloc[[2]])是df 中的第二个“行”。该行恰好位于 index 位置 4.loc 通过索引值查找它们。所以也许“iloc”就像A[i]中的“i”? :)
  • @Jeff - 这很好用,但是当您想从数据框中复制一行(例如df.loc[-1] = df.iloc[[0]])并插入它时会发生什么?该框架带有一个添加的索引列,给出错误ValueError: cannot set a row with mismatched columns(参见stackoverflow.com/questions/47340571/…
【解决方案2】:

DataFrame 索引运算符[] 的主要用途是选择列。

当索引运算符传递一个字符串或整数时,它会尝试查找具有该特定名称的列并将其作为系列返回。

因此,在上述问题中:df[2] 搜索与整数值 2 匹配的列名。此列不存在,并引发了 KeyError


DataFrame 索引操作符在使用切片表示法时完全改变了选择行的行为

奇怪的是,当给定一个切片时,DataFrame 索引运算符会选择行,并且可以通过整数位置或索引标签来选择行。

df[2:3]

这将从整数位置 2 到 3 的行开始切片,不包括最后一个元素。所以,只有一行。下面每第三行选择从整数位置 6 开始到但不包括 20 的行。

df[6:20:3]

如果您的 DataFrame 索引中有字符串,您也可以使用由字符串标签组成的切片。详情请见this solution on .iloc vs .loc

我几乎从不将这种切片符号与索引运算符一起使用,因为它不明确且几乎从未使用过。按行切片时,坚持使用.loc/.iloc

【讨论】:

  • 尝试使用 indxeing 运算符将行添加到另一个数据帧,但另一个数据帧仍然为空。为什么?
【解决方案3】:

您可以将 DataFrame 视为 Series 的字典。 df[key] 尝试通过key 选择列索引并返回一个Series对象。

但是在 [] 内部切片会切片行,因为这是一种非常常见的操作。

您可以阅读文档了解详情:

http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

【讨论】:

  • 感谢您的提示。有趣的是,这种事情有时仍然让熊猫质疑。在某些情况下为行为添加例外,.. 对我来说,这感觉就像为了一点方便而牺牲一致性。
【解决方案4】:

要对pandas表进行基于索引的访问,还可以考虑numpy.as_array选项将表转换为Numpy数组

np_df = df.as_matrix()

然后

np_df[i] 

会起作用的。

【讨论】:

  • 这违背了数据帧索引的全部目的以及 pandas 提供的所有其他内容
【解决方案5】:

你可以看看source code

DataFrame 有一个私有函数_slice()DataFrame 进行切片,它允许参数axis 确定要切片的轴。 __getitem__()DataFrame 在调用 _slice() 时不会设置轴。所以_slice()默认将它切片为0轴。

你可以做一个简单的实验,这可能对你有帮助:

print df._slice(slice(0, 2))
print df._slice(slice(0, 2), 0)
print df._slice(slice(0, 2), 1)

【讨论】:

    【解决方案6】:

    你可以像这样循环遍历数据框。

    for ad in range(1,dataframe_c.size):
        print(dataframe_c.values[ad])
    

    【讨论】:

      【解决方案7】:

      按照 Ted 的建议,我通常会选择 .loc/.iloc,但也可以通过转置 DataFrame 来选择一行。在上面的示例中,df.T[2] 为您提供df 的第 2 行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-21
        • 2015-06-13
        • 2014-10-11
        • 1970-01-01
        • 2016-04-19
        相关资源
        最近更新 更多