相同值的动态布尔掩码某些列pandas

时间:2016-06-21 09:07:01

标签: python pandas

我有一个Pandas DataFrame,其中某些行在类似的列中具有相同的值。我想创建一个布尔掩码,当所有这些列具有特定行的相同值时,该掩码为True。我想动态传递列表列表进行检查。例如:

A | B | C | Mask
1 | 1 | 1 | True
2 | 2 | 3 | False
4 | 4 | 4 | True

掩码应该由我传递给DataFrame的same_values函数和列表列表返回。例如

same_values(data, ['A', 'B', 'C'])

如果没有动态传递,我可以这样做:

data[(data['A']==data['B'])&(data['A']==data['C'])]

我可以动态迭代所有列并将它们与第一个传递的列进行比较,但这似乎效率低下。谁有更好的解决方案?

4 个答案:

答案 0 :(得分:1)

您可以将所有dfeq的第一列与all进行比较:

print (df.eq(df.iloc[:,0], axis=0))
      A     B      C
0  True  True   True
1  True  True  False
2  True  True   True

print (df.eq(df.iloc[:,0], axis=0).all(axis=1))
0     True
1    False
2     True
dtype: bool

如果只需要比较几列,请使用subset:

L = ['A','B','C']
print (df[L].eq(df.iloc[:,0], axis=0).all(axis=1))
0     True
1    False
2     True
dtype: bool

答案 1 :(得分:1)

在与同事讨论后,他向我指出了这篇文章:

Get rows that have the same value across its columns in pandas

我已经尝试了这里提到的两种方法,并在发布的链接上,结果如下:

%timeit test1 = test[test.apply(pd.Series.nunique, axis=1)==1]
1.23 s per loop

%timeit test2 = test[test.eq(test['A'], axis='index').all(1)]
3.47 ms per loop

%timeit test3 = test[test.apply(lambda x: x.duplicated(keep=False).all(), axis=1)]
2.3 s per loop

%timeit test4 = test[test.apply(lambda x: x == (x.iloc[0]).all(), axis=1)]
4.5 s per loop

答案 2 :(得分:1)

你可以试试这个:

data = pd.DataFrame({'a': [1, 2, 4], 'b': [1, 2, 4], 'c': [1, 3, 4]})
data.apply(lambda x: len(set(x)) == 1, axis=1) 

答案 3 :(得分:0)

这有多糟糕:

list_a = [1, 2, 4]
list_b = [1, 2, 4]
list_c = [1, 3, 4]

longshot = [True if not x % 111 else False for x in list(map(lambda x: int(str(x[0])+str(x[1])+str(x[2])), list(zip(list_a, list_b, list_c))))]
print(longshot) # [True, False, True]