Python 数据帧中重复项的识别

Python 数据帧中重复项的识别,python,python-2.7,pandas,dataframe,Python,Python 2.7,Pandas,Dataframe,使用python 2.7,我有以下数据帧“matches_df”: 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 我想要一个不包含重复游戏的列表。这些游戏有相同的两个玩家,不一定在同一列,并且在同一天进行。在上面的例子中,

使用python 2.7,我有以下数据帧“matches_df”:

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是重复的

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

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))
但是,这并没有按预期的那样工作,在数据框中创建了一个空白列


我在寻找中间步骤代码中的错误或推荐替代方法方面的帮助

按列[‘姓名’、‘对手’]对球员进行排序 如果它们相同但处于不同的位置,则排序会将它们置于相同的位置

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
然后连接字符串并添加列

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

虽然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方法的函数期望dataframe作为参数,并期望返回整个新列。你需要像上面的理解列表一样的东西,才能让它起作用

>>> 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
当然,这只是插入游戏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

也许可以看看strx.name生成了什么。与此答案完全重叠:。如果您只想删除一些列的重复项,这也很有趣。