说我下面有pandas DataFrame:
A B C D
1 foo one 0 0
2 foo one 2 4
3 foo two 4 8
4 cat one 8 4
5 bar four 6 12
6 bar three 7 14
7 bar four 7 14
我想选择A中具有相同值但B中具有不同值的所有行。因此,我希望代码的输出为:
A B C D
1 foo one 0 0
3 foo two 4 8
5 bar three 7 14
6 bar four 7 14
最有效的方法是什么?我大约有11,000行,列值有很大的差异,但是这种情况经常出现。在我的数据集中,如果列A中的元素相等,那么对应列B中的值也应该相等,但是由于贴错标签,情况并非如此,我想解决这个问题,因此我不愿意这样做一。
答案 0 :(得分:2)
result = df.groupby('A').filter(lambda g: len(g) > 1).groupby(['A', 'B']).head(1)
print(result)
输出
A B C D
0 foo one 0 0
2 foo two 4 8
4 bar four 6 12
5 bar three 7 14
第一个分组依据和过滤器将删除没有重复的A
值(即cat
)的行,第二个将创建具有相同的A, B
的组,并且对于每个行第一个元素。
答案 1 :(得分:2)
您可以尝试@Daniel的建议,groupby
+ filter
+ drop_duplicates
:
>>> df.groupby('A').filter(lambda g: len(g) > 1).drop_duplicates(subset=['A', 'B'], keep="first")
A B C D
0 foo one 0 0
2 foo two 4 8
4 bar four 6 12
5 bar three 7 14
或者,如果要在列A
和B
的子集之间放置重复项,则可以在下面使用,但是该行也将包含cat
。
>>> df.drop_duplicates(subset=['A', 'B'], keep="first")
A B C D
0 foo one 0 0
2 foo two 4 8
3 cat one 8 4
4 bar four 6 12
5 bar three 7 14
答案 2 :(得分:0)
当前答案是正确的,并且可能也更加复杂。如果您有复杂的条件,则filter函数将非常有用。如果您像我一样,并且希望保持简单,那么我认为跟随是一种更适合初学者的方式
>>> df = pd.DataFrame({
'A': ['foo', 'foo', 'foo', 'cat', 'bar', 'bar', 'bar'],
'B': ['one', 'one', 'two', 'one', 'four', 'three', 'four'],
'C': [0,2,4,8,6,7,7],
'D': [0,4,8,4,12,14,14]
}, index=[1,2,3,4,5,6,7])
>>> df = df.drop_duplicates(['A', 'B'], keep='last')
A B C D
2 foo one 2 4
3 foo two 4 8
4 cat one 8 4
6 bar three 7 14
7 bar four 7 14
>>> df = df[df.duplicated(['A'], keep=False)]
A B C D
2 foo one 2 4
3 foo two 4 8
6 bar three 7 14
7 bar four 7 14
keep='last'
在此处是可选的