Pandas 多重条件索引数据框的意外行为

Pandas 多重条件索引数据框的意外行为

在本文中,我们将介绍在 Pandas pandas 中使用多重条件索引数据框时可能会出现的意外行为。具体来说,我们将着眼于使用逻辑和符号 AND (&) 和符号 OR (|) 进行索引操作时可能遇到的问题,以及如何避免这些问题。

阅读更多:Pandas 教程

使用逻辑 AND 进行索引

在 Pandas pandas 中,当使用逻辑 AND 进行索引操作时,会出现以下的问题。假设有一个数据框 df,其中包含两列 x 和 y,我们想要选取同时满足以下条件的行:

  • df[‘x’] 大于 2;
  • df[‘y’] 小于 4。

我们可能会写出如下的代码:

df[(df['x'] > 2) and (df['y'] < 4)]
Python

然而,这段代码会提示 TypeError,因为 “and” 运算符不允许对 Pandas pandas 数据运算。正确的代码应该是使用符号 “&” 进行索引操作:

df[(df['x'] > 2) & (df['y'] < 4)]
Python

需要注意的是,符号”&” 和符号 “|” 的优先级比 “and” 和 “or” 要高,因此需要使用括号来分组条件。

使用逻辑 OR 进行索引

使用逻辑 OR 进行索引操作时也存在意外行为。假设我们想选取 df 数据框中所有满足以下条件的行:

  • df[‘x’] 等于 1;
  • df[‘y’] 大于 3 或者小于 2。

我们可能会写出如下的代码:

df[(df['x'] == 1) or ((df['y'] > 3) | (df['y'] < 2))]
Python

然而,这段代码同样会提示 TypeError。正确的代码应该是使用符号 “|” 进行索引操作:

df[(df['x'] == 1) | ((df['y'] > 3) | (df['y'] < 2))]
Python

需要注意的是,使用逻辑 OR 进行索引操作时,需要使用多个括号进行分组条件,以确保根据预期进行逻辑运算。

示例说明

为了更好地说明上述问题,我们在这里提供一个示例。假设我们有如下的数据框 df:

import pandas as pd

data = {'x': [0, 1, 2, 3, 4],
        'y': [2, 3, 4, 5, 6]}

df = pd.DataFrame(data)
Python

那么,如果我们使用逻辑 AND 进行如下的索引操作:

df[(df['x'] > 2) and (df['y'] < 4)]
Python

则会得到如下的错误信息:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-5f5398ec183a> in <module>
----> 1 df[df['x'] > 2 and df['y'] < 4]

/opt/conda/lib/python3.7/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2873             if is_iterator(key):
   2874                 key = list(key)
-> 2875             indexer = self.loc._get_listlike_indexer(key, axis=1, raise_missing=True)[1]
   2876 
   2877         # Take out the columns

/opt/conda/lib/python3.7/site-packages/pandas/core/indexing.py in _get_listlike_indexer(self, key, axis, raise_missing)
   1546             if len(ax) or not len(key):
   1547                 try:
-> 1548                     keyarr, indexer, new_indexer = ax._reindex_non_unique(keyarr)
   1549                 except PandasError as e:
   1550                     raise self._exception(keyarr, e)

/opt/conda/lib/python3.7/site-packages/pandas/core/index
Python

请忽略上文的错误代码,使用如下的代码进行索引操作:

df[(df['x'] > 2) & (df['y'] < 4)]
Python

则输出结果如下:

Empty DataFrame
Columns: [x, y]
Index: []
Python

我们发现这样的结果是意料之外的,因为 df 中满足条件的行应该是第四行 (3, 5) 而不是空数据框。这是由于使用逻辑 AND 运算符时,需要将每个条件用括号括起来,否则会因为优先级问题而导致出错。使用如下代码可以得到正确的结果:

df[(df['x'] > 2) & (df['y'] < 4)]
Python

输出结果为:

   x  y
3  3  5
Python

同样地,如果我们使用如下的代码进行索引操作:

df[(df['x'] == 1) or ((df['y'] > 3) | (df['y'] < 2))]
Python

则会得到如下的错误信息:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-db3fc4e3c9f6> in <module>
----> 1 df[(df['x'] == 1) or ((df['y'] > 3) | (df['y'] < 2))]

/opt/conda/lib/python3.7/site-packages/pandas/core/generic.py in __nonzero__(self)
   1534         raise ValueError("The truth value of a {0} is ambiguous. "
   1535                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1536                          .format(self.__class__.__name__))
   1537 
   1538     __bool__ = __nonzero__

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Python

这是由于使用逻辑 OR 运算符时,同样需要使用括号将每个条件分组,以确保根据预期进行逻辑运算。正确的代码为:

df[(df['x'] == 1) | ((df['y'] > 3) | (df['y'] < 2))]
Python

输出结果为:

   x  y
0  0  2
1  1  3
Python

总结

在 Pandas pandas 中使用多重条件索引数据框时,需要注意使用逻辑运算符的正确方式,并确保使用括号进行分组条件。忽略这些细节可能会导致意外的行为和错误结果。在实际应用中,我们应该注意这些细节以保证代码的正确性和稳定性。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册