在Pandas中查询NaN和其他名字

Ame*_*ina 31 python pandas

假设我有一个df包含value一些浮点值的列的数据框和一些NaN.如何NaN 使用查询语法获取数据框的一部分?

例如,以下内容不起作用:

df.query( '(value < 10) or (value == NaN)' )
Run Code Online (Sandbox Code Playgroud)

我得到name NaN is not defined(同样的df.query('value ==NaN'))

一般来说,有没有办法在查询中使用numpy的名称,如inf,nan,pi,e,等?

DSM*_*DSM 66

一般来说,你可以使用@local_variable_name,所以像

>>> pi = np.pi; nan = np.nan
>>> df = pd.DataFrame({"value": [3,4,9,10,11,np.nan,12]})
>>> df.query("(value < 10) and (value > @pi)")
   value
1      4
2      9
Run Code Online (Sandbox Code Playgroud)

会工作,但nan不等于自己,所以value == NaN永远是假的.解决这个问题的一种方法是使用这个事实,并value != value用作isnan检查.我们有

>>> df.query("(value < 10) or (value == @nan)")
   value
0      3
1      4
2      9
Run Code Online (Sandbox Code Playgroud)

>>> df.query("(value < 10) or (value != value)")
   value
0      3
1      4
2      9
5    NaN
Run Code Online (Sandbox Code Playgroud)

  • 应该有更好的方法来做到这一点......但我喜欢黑客. (4认同)
  • 好的,我现在明白了。设置`value == value` 然后适用于*排除* NaN (3认同)
  • 警告:这不适用于 pd.NA 条目(pandas 版本 1.0.3)。 (3认同)
  • @javadba:嗯,这一节的全部要点是要显示((value == @nan)`_doesn't_ work,因为nan不等于它本身,因此我使用`value!= value`技巧。 (2认同)

Jar*_*rno 23

您可以使用isna和方法,它简洁易读。notna Series

import pandas as pd
import numpy as np

df = pd.DataFrame({'value': [3, 4, 9, 10, 11, np.nan, 12]})
available = df.query("value.notna()")
print(available)

#    value
# 0    3.0
# 1    4.0
# 2    9.0
# 3   10.0
# 4   11.0
# 6   12.0

not_available = df.query("value.isna()")
print(not_available)

#    value
# 5    NaN
Run Code Online (Sandbox Code Playgroud)

如果您已numexpr安装,则需要通过engine="python"才能使其与.query. numexpr推荐的由熊猫加快的性能.query上更大的数据集。

available = df.query("value.notna()", engine="python")
print(available)
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用顶级pd.isna函数,将其作为局部变量引用。同样,engine="python"numexpr存在时需要通过。

import pandas as pd
import numpy as np


df = pd.DataFrame({'value': [3, 4, 9, 10, 11, np.nan, 12]})
df.query("@pd.isna(value)")

#    value
# 5    NaN
Run Code Online (Sandbox Code Playgroud)

  • 您的第一个示例在 Pandas 1.2.1 上返回 `*** TypeError: 'Series' 对象是可变的,因此它们不能被散列` (2认同)
  • 我认为这是正确的答案 - 不过 hack 很酷! (2认同)

Eri*_*ess 21

根据这个答案你可以使用:

df.query('value < 10 | value.isnull()', engine='python')
Run Code Online (Sandbox Code Playgroud)

我确认它有效.

  • @JakubKukul,这取决于列的数据类型。对于具有本机 NaN 的浮点数,则没有必要,但如果列是字符串或整数,则需要这样做。 (6认同)
  • 在这种情况下甚至不需要 `engine='python'` (5认同)
  • 脚本中的engine='python'在做什么? (2认同)
  • 它将表达式解释为 Python 表达式而不是 pandas 表达式 (numexpr)。https://pandas.pydata.org/docs/reference/api/pandas.eval.html#pandas.eval (2认同)

Are*_*Too 11

Pandas 使用 NumPy 的 nan 值填充 DataFrame 中的空单元格。事实证明,这有一些有趣的特性。首先,没有任何东西等于这种空,甚至它本身。因此,您无法通过检查任何特定的相等性来搜索它。

In : 'nan' == np.nan
Out: False

In : None == np.nan
Out: False

In : np.nan == np.nan
Out: False
Run Code Online (Sandbox Code Playgroud)

但是,由于包含 np.nan 值的单元格不会等于任何值,包括另一个 np.nan 值,因此我们可以检查它是否不等于自身。

In : np.nan != np.nan
Out: True
Run Code Online (Sandbox Code Playgroud)

您可以使用 Pandas 查询方法来利用这一点,只需搜索特定列中的值与其自身不相等的单元格即可。

df.query('a != a')
Run Code Online (Sandbox Code Playgroud)

或者

df[df['a'] != df['a']]
Run Code Online (Sandbox Code Playgroud)


as *_* if 10

对于value不为空的行

df.query("value == value")
Run Code Online (Sandbox Code Playgroud)

对于valuenull的行

df.query("value != value")
Run Code Online (Sandbox Code Playgroud)

  • 好的!我相信这是帖子作者想要的。 (2认同)
  • pandas/numpy NaN 中的@DipanwitaMallick!= NaN。所以 NaN 本身并不等于。 (2认同)
  • @DipanwitaMallick 我的评论可能有点太短了。在 pandas/numpy NaN != NaN 中。所以 NaN 本身并不等于。因此,要检查单元格是否具有 NaN 值,您可以检查 cell_value != cell_value -&gt; 仅适用于 NaN(3 != 3 为 False,但 NaN != NaN 为 True,并且该查询仅返回 True 的值 - &gt; NaN)。要检查单元格是否没有 NaN,请检查 cell_value == cell_value -&gt; 这仅对于非 NaN 为 true(3 == 3 为 True,但 NaN == NaN 为 False,并且该查询仅返回 True -&gt;不是 NaN)。 (2认同)