忽略 nan 的 Python 比较

标签 python python-2.7 pandas nan equality

虽然 nan == nan 始终是 False,但在许多情况下人们希望平等对待它们,这体现在 pandas.DataFrame.equals 中。 :

NaNs in the same location are considered equal.

我当然会写

def equalp(x, y):
    return (x == y) or (math.isnan(x) and math.isnan(y))

但是,这将在 [float("nan")]isnan 等非数字 barfs 容器上失败(所以 the complexity increases )。

那么,人们如何比较可能包含 nan 的复杂 Python 对象?

附言。动机:比较 pandas DataFrame 中的两行时,我会 convert them into dicts并按元素比较字典。

PPS。当我说“比较”时,我在想 diff , 不是 equalp .

最佳答案

假设您有一个包含 nan 值的数据框:

In [10]: df = pd.DataFrame(np.random.randint(0, 20, (10, 10)).astype(float), columns=["c%d"%d for d in range(10)])

In [10]: df.where(np.random.randint(0,2, df.shape).astype(bool), np.nan, inplace=True)

In [10]: df
Out[10]:
     c0    c1    c2    c3    c4    c5    c6    c7   c8    c9
0   NaN   6.0  14.0   NaN   5.0   NaN   2.0  12.0  3.0   7.0
1   NaN   6.0   5.0  17.0   NaN   NaN  13.0   NaN  NaN   NaN
2   NaN  17.0   NaN   8.0   6.0   NaN   NaN  13.0  NaN   NaN
3   3.0   NaN   NaN  15.0   NaN   8.0   3.0   NaN  3.0   NaN
4   7.0   8.0   7.0   NaN   9.0  19.0   NaN   0.0  NaN  11.0
5   NaN   NaN  14.0   2.0   NaN   NaN   0.0   NaN  NaN   8.0
6   3.0  13.0   NaN   NaN   NaN   NaN   NaN  12.0  3.0   NaN
7  13.0  14.0   NaN   5.0  13.0   NaN  18.0   6.0  NaN   5.0
8   3.0   9.0  14.0  19.0  11.0   NaN   NaN   NaN  NaN   5.0
9   3.0  17.0   NaN   NaN   0.0   NaN  11.0   NaN  NaN   0.0

如果您想比较行,比如第 0 行和第 8 行。那么只需使用 fillna 并进行矢量化比较:

In [12]: df.iloc[0,:].fillna(0) != df.iloc[8,:].fillna(0)
Out[12]:
c0     True
c1     True
c2    False
c3     True
c4     True
c5    False
c6     True
c7     True
c8     True
c9     True
dtype: bool

如果您只想知道哪些列不同,您可以使用生成的 bool 数组对列进行索引:

In [14]: df.columns[df.iloc[0,:].fillna(0) != df.iloc[8,:].fillna(0)]
Out[14]: Index(['c0', 'c1', 'c3', 'c4', 'c6', 'c7', 'c8', 'c9'], dtype='object')

关于忽略 nan 的 Python 比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48452933/

相关文章:

python - 如何调整 seaborn catplot 的大小

python - 在python中读取资源文件

python - 如何调用派生类方法?

python - DtypeWarning : Columns (15, 16,18,24) 有混合类型。如果列具有混合类型,则会被删除

python - Jenkins 安全中止子进程

python - 如何在 pandas 数据框行中附加所有具有相同 id 的元素?

python - 重新排序簇号以实现正确对应

Python:从另一个文件打印字符串

python - pandas,to_csv()转为特定格式

python - 如何返回包含多个数据框的列名的数据框