假设我有一个数据框df
,其中一列value
保存了一些浮点数和一些NaN
。如何使用查询语法获取包含NaN
的数据框的部分?
例如,下面的代码不起作用:
df.query( '(value < 10) or (value == NaN)' )
我得到了 name NaN未定义
的错误信息(对于 df.query('value ==NaN')
也是同样的错误)
通常情况下,是否有办法在查询中使用 numpy 的名称,例如 inf
、nan
、pi
、e
等等?
一般情况下,您可以使用@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
虽然 nan
可以起到作用,但是它本身不等于自己,因此 value == NaN
总是为 false。绕过这个问题的一种方法是利用这个事实,使用 value != value
作为 isnan
检查。我们有:
>>> df.query("(value < 10) or (value == @nan)")
value
0 3
1 4
2 9
但是
>>> df.query("(value < 10) or (value != value)")
value
0 3
1 4
2 9
5 NaN
@nan
"技巧" 对于 numpy
变量(例如 nan = numpy.nan
)不起作用。但它可以过滤掉其他 字符串。 - WestCoastProjects(value == @nan)
不起作用的原因,因为NaN不等于它本身,所以我使用了value != value
的技巧。 - DSMvalue
设置为value
就可以排除NaN。 - WestCoastProjectsisna
和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
numexpr
,需要传递engine="python"
才能使其与.query
一起正常工作。pandas建议使用numexpr
来加速处理大型数据集时的.query
性能。available = df.query("value.notna()", engine="python")
print(available)
另外,您可以使用顶级 pd.isna
函数,通过将其引用为本地变量来使用。当存在 numexpr
时,再次传递 engine="python"
是必需的。
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
*** TypeError: 'Series' 对象是可变的,因此它们不能被哈希
。 - Keto当 value
不为 null 时
df.query("value == value")
当value
为空时,对于这些行
df.query("value != value")
In : 'nan' == np.nan
Out: False
In : None == np.nan
Out: False
In : np.nan == np.nan
Out: False
然而,一个包含np.nan的单元格将不等于 任何东西,甚至是另一个np.nan值, 因此我们可以检查它是否与自身不相等。
In : np.nan != np.nan
Out: True
你可以利用Pandas的查询方法,通过查找特定列中值与自身不相等的单元格来利用此功能。df.query('a != a')
或者df[df['a'] != df['a']]
df.query("value == 'NaN'")
我认为其他答案通常会更好。在某些情况下,我的查询必须通过 eval(非常小心地使用 eval)并且下面的语法很有用。要求一个数字既小于又大于等于排除所有数字,仅剩下类似 null 的值。
df = pd.DataFrame({'value':[3,4,9,10,11,np.nan, 12]})
df.query("value < 10 or (~(value < 10) and ~(value >= 10))")
engine='python'
并不是必需的。 - Jakub Kukul