如何统计pandas中DataFrame的两列定义值差的个数?

How to count the number of defined value differences between two columns of DataFrame in pandas?

假设我有一个 pandas DataFrame 定义如下:

    a     b
0  N/A    3
1   1     1
2   2     0
3   2    N/A
4   0     1
5  N/A   N/A

我想计算出在 ab 两列中有多少行具有不相等的值。在此示例中,有两个这样的行,索引为 2 和 4。索引 0、3 和 5 在至少一列中包含未定义的值,索引 1 的行具有相等的值。

我考虑的方法是删除 ab 中所有包含未定义值的行,然后删除 f.e。取两列之间的差异并计算零的数量。

使用 boolean indexing 和 2 个掩码:

df1 = df[(df['a'].isnull() == df['b'].isnull()) & (df['a'] != df['b'])]
print (df1)
     a    b
2  2.0  0.0
4  0.0  1.0

详情:

print ((df['a'].isnull() == df['b'].isnull()))
0    False
1     True
2     True
3    False
4     True
dtype: bool

print ((df['a'] != df['b']))
0     True
1    False
2     True
3     True
4     True
dtype: bool

print ((df['a'].isnull() == df['b'].isnull()) & (df['a'] != df['b']))
0    False
1    False
2     True
3    False
4     True
dtype: bool

使用多列的一般解决方案 - 首先通过 all and chain for compare DataFrame by first column by eq and return at least one True per row by any 检查所有真值是否不是每行 NaNs:

df1 = df[df.notnull().all(axis=1) & df.ne(df.iloc[:, 0], axis=0).any(axis=1)]
print (df1)
     a    b
2  2.0  0.0
4  0.0  1.0

详情:

print (df.notnull())
       a      b
0  False   True
1   True   True
2   True   True
3   True  False
4   True   True

print (df.notnull().all(axis=1))
0    False
1     True
2     True
3    False
4     True
dtype: bool

print (df.ne(df.iloc[:, 0], axis=0))
       a      b
0   True   True
1  False  False
2  False   True
3  False   True
4  False   True

print (df.ne(df.iloc[:, 0], axis=0).any(axis=1))
0     True
1    False
2     True
3     True
4     True
dtype: bool

另一个解决方案:

df = df[(df['a'].notnull()) & (df['b'].notnull()) & (df['a'] != df['b'])]
print (df)
     a    b
2  2.0  0.0
4  0.0  1.0

通过逻辑比较,您有一种内置的方法可以做到这一点,并且不会浪费资源来对列求和。

假设:

>> import numpy as np
>> import pandas as pd     
>> d = { 'a': [np.NaN, 1 , 2 , 2 , 0], 'b': [3, 1, 0 , np.NaN, 1]}
>> df = pd.DataFrame(d)

最简单的方法可能是:

>> df.dropna().a != df.dropna().b

    1    False
    2     True
    4     True
    dtype: bool

您显然可以将同样的事情扩展到更多列。

我会这样使用 pandas.DataFrame.apply

df.dropna().apply(lambda x: x.a != x.b, axis=1)

只需删除所有 NaN 值,然后按元素比较两列。

结果是

1    False
2    True
4    True

这是使用 pd.DataFrame.dropna and pd.DataFrame.query 的一种方法。

count = len(df.dropna().query('a != b'))  # 2

res = df.dropna().query('a != b')

print(res)

     a    b
2  2.0  0.0
4  0.0  1.0