我有一个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'])]
我可以动态迭代所有列并将它们与第一个传递的列进行比较,但这似乎效率低下。谁有更好的解决方案?
答案 0 :(得分:1)
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]