从Pandas DataFrame中选择一列中具有相同值而另一列中具有不同值的行

时间:2019-01-04 17:11:04

标签: python pandas dataframe select rows

说我下面有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中的值也应该相等,但是由于贴错标签,情况并非如此,我想解决这个问题,因此我不愿意这样做一。

3 个答案:

答案 0 :(得分:2)

使用groupby + filter + head

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

或者,如果要在列AB的子集之间放置重复项,则可以在下面使用,但是该行也将包含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'在此处是可选的