2016-12-29 36 views
2

我有以下的數據框「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

也許看看'str(x.name)'產生了什麼。 – lmo

+0

與此答案相當重疊:http:// stackoverflow。COM /問題/ 23667369 /下拉所有複本行式的Python-大熊貓。如果你想刪除重複的只有幾個列也很有趣。 – PlagTag

回答

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

雖然這已經被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