如何在pandas中计算DataFrame的两列之间已定义值差异的数量?

3
假设我有一个如下定义的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中未定义值的行,然后找到两列之间的差异并计算零的数量。

1
你能解释得更详细一些吗?你想检查所有列中的值 0 并返回行吗?还是其他什么?谢谢。 - jezrael
4个回答

2
使用2个掩码进行布尔索引:boolean indexing
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检查每行中所有的True是否不是NaN,然后通过eq与第一列比较并使用any返回每行至少一个True

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

我忘了提到,我不希望出现两列都是 N/A 的情况。 - Krzysztof Słowiński
df[(df['a'].isnull() == False) & (df['b'].isnull() == False) & (df['a'] != df['b'])] ? df[(df['a'].notnull()) & (df['b'].notnull()) & (df['a'] != df['b'])] ? - Krzysztof Słowiński
或者 df[(df['a'].notnull()) & (df['b'].notnull()) & (df['a'] != df['b'])] 更简洁... - jezrael

2

这是使用 pd.DataFrame.dropnapd.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

1
使用逻辑比较,您可以内置一种方法来完成此操作,而无需浪费资源对列进行求和。
假设:
>> 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

你显然可以将同样的方法扩展到更多列。

1
我会这样使用pandas.DataFrame.apply
df.dropna().apply(lambda x: x.a != x.b, axis=1)

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

结果是

1    False
2    True
4    True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接