我目前正在使用 Pandas 数据框,我想选择数据框中没有 None 实体属性的所有数据条目。
df_ = df.loc[df['entities'] != None]
Run Code Online (Sandbox Code Playgroud)
似乎工作得很好但是
df_ = df.loc[df['entities'] is not None]
Run Code Online (Sandbox Code Playgroud)
将引发 KeyError 是
文件“pandas_libs\index.pyx”,第 107 行,>pandas._libs.index.IndexEngine.get_loc 文件“pandas_libs\index.pyx”,第 128 行,>pandas._libs.index.IndexEngine.get_loc 文件“pandas_libs\ index_class_helper.pxi”,第 91 行,在 >pandas._libs.index.Int64Engine._check_type KeyError: True
好吧,我已经知道我原来的问题的解决方案,我只是好奇为什么会发生这种情况
代替
df_ = df.loc[df['entities'] is not None]
Run Code Online (Sandbox Code Playgroud)
或者
df_ = df.loc[df['entities'] != None]
Run Code Online (Sandbox Code Playgroud)
你应该使用
df_ = df.loc[df['entities'].isna()]
Run Code Online (Sandbox Code Playgroud)
因为pandas 中缺失值的表示与通常的python 用None 表示缺失值的方式不同。特别是您会收到关键错误,因为df['entities']检查列系列的身份与None. 这True在任何情况下都为 ,因为该系列不是None。然后.loc在行索引中搜索True,这在您的情况下不存在,因此会引发异常。!=不会导致引发此异常,因为相等运算符被重载pandas.Series(否则您无法通过将列与固定值(如 in 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()
Run Code Online (Sandbox Code Playgroud)
它返回:
Out[18]:
0 True
1 True
2 False
Name: nulls, dtype: bool
Run Code Online (Sandbox Code Playgroud)
但代码:
df['nulls'] == None
Run Code Online (Sandbox Code Playgroud)
返回
Out[20]:
0 False
1 False
2 False
Name: nulls, dtype: bool
Run Code Online (Sandbox Code Playgroud)
如果查看列中存储的对象的数据类型,您会发现它们都是浮点数:
df['nulls'].map(type)
Out[19]:
0 <class 'float'>
1 <class 'float'>
2 <class 'float'>
Name: nulls, dtype: object
Run Code Online (Sandbox Code Playgroud)
对于其他类型的列,缺失值的表示甚至可能不同。例如,如果您使用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
Run Code Online (Sandbox Code Playgroud)
因此,使用isna()代替!= None还可以帮助您保持代码干净,以免处理熊猫内部数据表示。
我在这里有点冒险,因为我没有 Pandas 的经验,但有 Python\xe2\x80\xa6 的经验
\n\nPanda 的神奇过滤[]很大程度上基于运算符重载。在这个表达式中:
df.loc[df[\'entities\'] != None]\nRun Code Online (Sandbox Code Playgroud)\n\ndf[\'entities\']是一个实现该__ne__方法的对象。这意味着你本质上是在做:
df.loc[df[\'entities\'].__ne__(None)]\nRun Code Online (Sandbox Code Playgroud)\n\n正在df[\'entities\'].__ne__(None)产生一些新的魔法条件对象。该df.loc对象实现了__getitem__重载下[]标语法的方法,因此整个事情本质上是:
df.loc.__getitem__(df[\'entities\'].__ne__(None))\nRun Code Online (Sandbox Code Playgroud)\n\n另一方面,is运算符不可重载。__is__对象无法实现任何方法,因此df[\'entities\'] is not None按照 Python 的核心规则进行计算,并且由于df[\'entities\']可能实际上不是None,因此该表达式的结果是True。所以就:
df.loc.__getitem__(True)\nRun Code Online (Sandbox Code Playgroud)\n\n这就是错误消息抱怨KeyError: True.
| 归档时间: |
|
| 查看次数: |
3343 次 |
| 最近记录: |