识别pandas数据帧中的重复项

时间:2016-12-29 19:07:51

标签: python python-2.7 pandas dataframe

我有以下数据框' matches_df',使用python 2.7:

name | opponent | date     | win
'Bob'    'Bill'   7/12/16     Y
'Mike'   'Matt'   4/15/18     N
'Tim'    'Tom'    1/1/11      N
'Bill'   'Bob'    7/12/16     N

我想要一个不包含重复游戏的列表。这些游戏具有相同的两个玩家(不一定在同一列中),并且发生在同一个日期。在上面的例子中,游戏1和游戏4是重复的。

为了解决这个问题,我尝试创建第4列game_id,它创建了前3列的排序组合。我想要这个结果:

name | opponent | date    | win | game_id
'Bob'    'Bill'   7/12/16    Y   '7/12/16 Bill Bob'  
'Mike'   'Matt'   4/15/18    N   '4/15/18 Matt Mike'
'Tim'    'Tom'    1/1/11     N   '1/1/11 Tim Tom'
'Bill'   'Bob'    7/12/16    N   '7/12/16 Bill Bob'

我使用了以下代码:

def sort_and_squash(a,b,c):
    return ''.join(sorted([str(a),str(b),str(c)]))
matches_df = matches_df.assign(game_id = lambda x: sort_and_squash(x.name,x.opponent,x.date))

但是,这不能按预期工作,在数据框中创建一个空白列。

我正在寻找帮助,无论是在我的代码中找到中间步骤的错误还是推荐替代方法。

2 个答案:

答案 0 :(得分:3)

对列['name', 'opponent']中的玩家进行排序 如果它们是相同的但位于不同的位置,则排序将使它们处于相同的位置。

game_id_df = df[['date']].join(df[['name', 'opponent']].apply(sorted, 1))
print(game_id_df)

      date  name opponent
0  7/12/16  Bill      Bob
1  4/15/18  Matt     Mike
2   1/1/11   Tim      Tom
3  7/12/16  Bill      Bob

然后join字符串并添加列

df['game_id'] = game_id_df.apply(tuple, 1).str.join(' ')
print(df)

   name opponent     date win            game_id
0   Bob     Bill  7/12/16   Y   7/12/16 Bill Bob
1  Mike     Matt  4/15/18   N  4/15/18 Matt Mike
2   Tim      Tom   1/1/11   N     1/1/11 Tim Tom
3  Bill      Bob  7/12/16   N   7/12/16 Bill Bob

现在您可以使用game_id删除重复项

print(df.drop_duplicates(subset=['game_id']))

   name opponent     date win            game_id
0   Bob     Bill  7/12/16   Y   7/12/16 Bill Bob
1  Mike     Matt  4/15/18   N  4/15/18 Matt Mike
2   Tim      Tom   1/1/11   N     1/1/11 Tim Tom

答案 1 :(得分:1)

虽然piRSquared已经回答了这个问题,但如果您更接近原始方法(或者您想了解原始方法无效的原因),您可以试试这个。

def sort_and_squash(df):
    return [' '.join(sorted([d.strftime('%m/%d/%Y'), n, o]))
            for d, n, o in zip(df.date, df.name, df.opponent)]

matches_df = matches_df.assign(game_id=sort_and_squash)

传递给assign方法的函数需要将数据帧作为参数,并期望返回整个新列。你需要像上面的列表理解这样的东西才能使它发挥作用。

>>> print matches_df
        date  name opponent win               game_id
0 2016-07-12   Bob     Bill   Y   07/12/2016 Bill Bob
1 2018-04-15  Mike     Matt   N  04/15/2018 Matt Mike
2 2011-01-01   Tim      Tom   N    01/01/2011 Tim Tom
3 2016-07-12  Bill      Bob   N   07/12/2016 Bill Bob

当然,这只是插入game_id列;它不会消除重复。要消除它们,您还需要:

matches_df = matches_df.drop_duplicates(subset=['game_id'])

然后:

>>> print matches_df
        date  name opponent win               game_id
0 2016-07-12   Bob     Bill   Y   07/12/2016 Bill Bob
1 2018-04-15  Mike     Matt   N  04/15/2018 Matt Mike
2 2011-01-01   Tim      Tom   N    01/01/2011 Tim Tom

最后一次触摸,如果您不再需要game_id列,可以将其删除:

matches_df = matches_df.drop('game_id', 1)

给你:

>>> print matches_df
        date  name opponent win
0 2016-07-12   Bob     Bill   Y
1 2018-04-15  Mike     Matt   N
2 2011-01-01   Tim      Tom   N