我当前正在使用Pandas数据框,我想选择该数据框中没有None实体属性的所有数据条目。
df_ = df.loc[df['entities'] != None]
似乎工作得很好 但是
df_ = df.loc[df['entities'] is not None]
将引发KeyError
> pandas._libs.index.IndexEngine.get_loc中的文件“ pandas_libs \ index.pyx”,第107行 > pandas._libs.index.IndexEngine.get_loc中的文件“ pandas_libs \ index.pyx”,第128行 > pandas._libs.index.Int64Engine._check_type中的文件“ pandas_libs \ index_class_helper.pxi”,第91行 KeyError:True
我已经知道解决原始问题的方法了,我很好奇为什么会发生这种情况
答案 0 :(得分:3)
我有点不高兴,因为我没有使用Pandas的经验,但是没有使用Python的经验……
熊猫通过[]
进行的魔术过滤很大程度上基于运算符的重载。在此表达式中:
df.loc[df['entities'] != None]
df['entities']
是实现__ne__
方法的对象。这意味着您实际上是在做:
df.loc[df['entities'].__ne__(None)]
df['entities'].__ne__(None)
正在产生一些新的魔术条件对象。 df.loc
对象实现了__getitem__
方法来重载[]
下标语法,因此,整个过程本质上是:
df.loc.__getitem__(df['entities'].__ne__(None))
另一方面,is
operator不可重载。没有对象可以实现的__is__
方法,因此df['entities'] is not None
的评估与Python的核心规则一样,并且由于df['entities']
可能实际上不是None
,因此其结果表达式为True
。因此:
df.loc.__getitem__(True)
这就是错误消息抱怨KeyError: True
的原因。
答案 1 :(得分:0)
代替
df_ = df.loc[df['entities'] is not None]
或
df_ = df.loc[df['entities'] != None]
您宁愿使用
df_ = df.loc[df['entities'].isna()]
因为熊猫中缺失值的表示方式与通常的Python用None(无)表示缺失值的方式不同。特别是您会得到关键错误,因为检查了列系列df['entities']
与None
的身份。在任何情况下,此结果的值为True
,因为该系列不是None
。然后.loc
在行索引中搜索True
(在您的情况下不存在),因此引发异常。 !=
不会引发此异常,因为相等运算符被pandas.Series
重载(否则,您无法通过比较具有固定值的列来构建索引器,如df['name'] == 'Miller'
)。此重载方法执行逐元素比较,并且其自身返回与.loc
方法配合使用的索引器。只是结果可能不是您想要的。
例如如果你这样做
import pandas as pd
import numpy as np
df= pd.DataFrame(dict(x=[1,2,3], y=list('abc'), nulls= [None, np.NaN, np.float32('inf')]))
df['nulls'].isna()
它返回:
Out[18]:
0 True
1 True
2 False
Name: nulls, dtype: bool
但代码:
df['nulls'] == None
返回
Out[20]:
0 False
1 False
2 False
Name: nulls, dtype: bool
如果查看存储在列中的对象的数据类型,您会发现它们都是浮点数:
df['nulls'].map(type)
Out[19]:
0 <class 'float'>
1 <class 'float'>
2 <class 'float'>
Name: nulls, dtype: object
对于其他类型的列,缺失值的表示甚至可能不同。例如。如果您使用Int64
列,则看起来像这样:
df['nulls_int64']= pd.Series([None, 1 , 2], dtype='Int64')
df['nulls_int64'].map(type)
Out[26]:
0 <class 'float'>
1 <class 'int'>
2 <class 'int'>
Name: nulls_int64, dtype: object
因此,使用isna()
而不是!= None
还可帮助您避免处理熊猫内部数据表示形式的代码。