Python 为什么pandas DataFrame的[](_getitem__)有时选择列,有时选择行?

Python 为什么pandas DataFrame的[](_getitem__)有时选择列,有时选择行?,python,pandas,Python,Pandas,给定此数据帧: In [40]: df = pd.DataFrame({'A': [1, 1], 'B': [2, 2], 'C': [3, 3]}) In [41]: df Out[41]: A B C 0 1 2 3 1 1 2 3 如果我将字符串列表传递给[],它将筛选列: In [42]: df[['A', 'C']] Out[42]: A C 0 1 3 1 1 3 但如果我将布尔值列表传递给[],它将过滤行: In [45]: df[[Tr

给定此数据帧:

In [40]: df = pd.DataFrame({'A': [1, 1], 'B': [2, 2], 'C': [3, 3]})

In [41]: df
Out[41]:
   A  B  C
0  1  2  3
1  1  2  3
如果我将字符串列表传递给[],它将筛选列:

In [42]: df[['A', 'C']]
Out[42]:
   A  C
0  1  3
1  1  3
但如果我将布尔值列表传递给[],它将过滤行:

In [45]: df[[True, False]]
Out[45]:
   A  B  C
0  1  2  3

有没有一种方法可以考虑这种差异,而不仅仅是它的现状?

我的理解是,这种复制R的行为使R脚本的迁移更容易,它也从ix开始,ix已被弃用。有很多方法可以进行切片,但现在我们的方法更少了:

单个项目,获取一列。 列列表,获取子帧 布尔索引 就我个人而言,我喜欢使用_getitem _uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

In [11]: df[['A', 'C']]
Out[11]:
   A  C
0  1  3
1  1  3

In [12]: df['A']
Out[12]:
0    1
1    1
Name: A, dtype: int64
另一种选择是,尽管其模糊性较小,但loc或iloc过于冗长:

In [13]: df.loc[:, ['A', 'B']]
Out[13]:
   A  B
0  1  2
1  1  2

In [14]: df.loc[:, 'A']
Out[14]:
0    1
1    1
Name: A, dtype: int64
值得注意的是,布尔屏蔽并不含糊,除非您有一个深奥的示例,其中布尔列和输入长度与数据帧匹配:

In [21]: df1 = pd.DataFrame({True: [1, 2], False: [3, 4]})

In [22]: df1
Out[22]:
   False  True
0      3      1
1      4      2

In [23]: df1[[True, False]]  # boolean slicing (not as column names)
Out[23]:
   False  True
0      3      1
从历史上看,ix中存在潜在的模糊性以及性能问题——有很多可能的途径可供选择。因此,除了消除歧义外,向loc和iloc的移动还导致了更快的代码—如果可以的话,通常使用iloc—它是最快的。

文档中提到,[]运算符的提供更多是为了方便。因此,它是对行还是对列起作用似乎取决于被认为是常见的操作

Python和NumPy索引运算符[]和属性运算符。跨广泛的用例快速方便地访问pandas数据结构。这使得交互工作变得直观,因为如果您已经知道如何处理Python字典和NumPy数组,那么就没有什么新的东西需要学习了。然而,由于要访问的数据类型事先未知,直接使用标准运算符有一些优化限制。对于生产代码,我们建议您利用本章中公开的优化数据访问方法

使用DataFrame,在[]内部切片会对行进行切片。这主要是为了方便,因为这是一种常见的操作

您可以使用与数据帧索引长度相同的布尔向量从数据帧中选择行

由于使用[]进行索引必须处理很多情况,如单标签访问、切片、布尔索引等,因此要找出您需要的内容,它会有一点开销

到目前为止,我发现:

选择行

布尔索引df[[True,False]] 切片df[0:1] 选择列

单标签df['A'] 标签列表df['A',C']]
尽管他们选择了看似合理的行为,但事实就是如此。此外,似乎没有关于[]索引运算符的明确文档-至少这会有所帮助。

是的,关键是df[…]通常会尝试将传递给_getitem的任何内容作为列索引器应用,但传递布尔掩码的情况除外。例如,尝试df[[0,1]],您将看到。这不是很不直观吗?我认为布尔掩码仍然会选择列。似乎最好的做法是始终使用.loc,它显式地具有行索引和列索引。确实,这是最好的做法,但如果您知道自己在做什么,它可以帮助您减少一些字符;实际上,出于优化的原因,建议在生产代码中使用.loc方法或.iloc方法。[]索引运算符基本上是一种“方便”的方法:它的设计目的是让您在一些最常见的用例中以最少的字符数访问数据值。大多数情况下,我将使用.loc而不是[]。R在[]方面没有这种模糊性,这就是我感到困惑的原因。df[…]总是过滤R中的列,例如df[c'A',c']和df[cTRUE,FALSE,TRUE]都保留A列和c列。@Heisenberg在R中我想应该是df[,cTRUE,FALSE,TRUE]?逻辑索引和我想的熊猫一样。。。在R中,正如您所说,我们可以对子集执行df[行索引,列索引]。我们还可以使用df[col_index]来选择列,col_index可以是标签、整数或布尔值。df[col_index]总是选择R中的列,这就是我所说的R对于[]没有这种模糊性。