2017-10-13 65 views
1

考慮以下兩個data.frames在Python 3使用大熊貓創建:刪除在在python另一個data.frame確切的行和一個data.frame的行頻率3

a1 = pd.DataFrame(({'A': [1, 2, 3, 4, 5, 2, 4, 2], 'B': ['a', 'b', 'c', 'd', 'e', 'b', 'd', 'b']})) 
a2 = pd.DataFrame(({'A': [1, 2, 3, 2], 'B': ['a', 'b', 'c', 'b']})) 

我想刪除在A2 A1的確切行,這樣的結果應該是:

A B 
4 d 
5 e 
4 d 
2 b 

注意,一排在A1 2 b爲保留在最終結果(實際上只有其中的一個被與一個取消在a2)中。有沒有在熊貓或任何其他庫中的任何內置函數來獲得這個結果?

+0

這個術語是但不幸的是'pd.Index.difference()'不足以應付,儘管它意味着集合差異。我希望能使用像'pd.Index(a1).difference(a2)'這樣的東西,但它不能正確處理非唯一的項目。 –

+0

約翰Zwinck我今天瞭解到'索引(a1)'。希望我完成了你的方法 – Dark

回答

1

允許使用GROUPBY cumcount:

a1['count'] = a1.groupby(['A','B']).cumcount() 
a2['count'] = a2.groupby(['A','B']).cumcount() 

選項1 - 合併和查詢選項2

df = (pd.merge(a1,a2, indicator=True, how='left') 
     .query("_merge != 'both'") 
     .drop(['_merge','count'], 1)) 

- 隨着折射率差合併即

i = a1.index.difference(a1.merge(a2,on=['A','B','count']).index) 
df = a1.loc[i].drop('count',1) 
0後

選項3 - 完成@約翰Zwinck的做法

df =pd.DataFrame(pd.Index(a1).difference(pd.Index(a2)).tolist(),columns=a2.columns).drop(['count'],1) 

輸出: 「差集」

 
    A B 
3 4 d 
4 5 e 
6 4 d 
7 2 b 
+1

棒極了!它確實給我想要的東西。 – RBL

+0

@RBL做投票,不要忘記接受答案。 – Dark

1

使用的list的定義和remove

l1=a1.values.tolist() 
l2=a2.values.tolist() 
for x in l2: 
    l1.remove(x) 

pd.DataFrame(l1,columns=a1.columns) 

Out[173]: 
    A B 
0 4 d 
1 5 e 
2 4 d 
3 2 b 

時間


巴拉斯的 1日。

start_time = timeit.default_timer() 
a1['count'] = a1.groupby(['A','B']).cumcount() 
a2['count'] = a2.groupby(['A','B']).cumcount() 
df = (pd.merge(a1,a2, indicator=True, how='left') 
     .query("_merge != 'both'") 
     .drop(['_merge','count'], 1)) 
print(timeit.default_timer() - start_time) 
0.012827654755454887 

2nd。

start_time = timeit.default_timer() 
a1['count'] = a1.groupby(['A','B']).cumcount() 
a2['count'] = a2.groupby(['A','B']).cumcount() 
i = a1.index.difference(a1.merge(a2,on=['A','B','count']).index) 
df = a1.loc[i].drop('count',1) 
print(timeit.default_timer() - start_time) 
0.05914717068662867 

3rd。

start_time = timeit.default_timer() 
a1['count'] = a1.groupby(['A','B']).cumcount() 
a2['count'] = a2.groupby(['A','B']).cumcount() 
df =pd.DataFrame(pd.Index(a1).difference(pd.Index(a2)).tolist(),columns=a2.columns).drop(['count'],1) 
print(timeit.default_timer() - start_time) 
0.006586597486375467 

礦:

start_time = timeit.default_timer() 
l1=a1.values.tolist() 
l2=a2.values.tolist() 
for x in l2: 
    l1.remove(x) 
pd.DataFrame(l1,columns=a1.columns) 
print(timeit.default_timer() - start_time) 
0.0028012795203835594 

數據輸入樣本的100倍。

a1=pd.concat([a1]*100,axis=0) 
a2=pd.concat([a2]*100,axis=0) 
+0

是的,它確實給出了我正在尋找的結果,但有沒有辦法避免循環,因爲我的data.frames包含數千和數千行以及大約10列。 – RBL

+2

這樣一個不錯的downvote你能給我理由嗎? – Wen

+1

它是一個很好的解決方案,不知道爲什麼downvote。我upvoted。 – Dark

相關問題