我有以下数据框' 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))
但是,这不能按预期工作,在数据框中创建一个空白列。
我正在寻找帮助,无论是在我的代码中找到中间步骤的错误还是推荐替代方法。
答案 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