2016-05-19 14 views
5

कैसे एक और dataframe से एक पांडा dataframe दूर करने के लिए, बस सेट घटाव की तरह:एक और dataframe से एक पांडा dataframe दूर करने के लिए कैसे

a=[1,2,3,4,5] 
b=[1,5] 
a-b=[2,3,4] 

और अब हम दो पांडा dataframe है, DF1 से df2 निकालने का तरीका:

In [5]: df1=pd.DataFrame([[1,2],[3,4],[5,6]],columns=['a','b']) 
In [6]: df1 
Out[6]: 
    a b 
0 1 2 
1 3 4 
2 5 6 


In [9]: df2=pd.DataFrame([[1,2],[5,6]],columns=['a','b']) 
In [10]: df2 
Out[10]: 
    a b 
0 1 2 
1 5 6 

तो हम उम्मीद करते हैं DF1-df2 परिणाम होगा:

In [14]: df 
Out[14]: 
    a b 
0 3 4 

यह कैसे करना है?

धन्यवाद।

+0

[पांडा के लिए सेट अंतर] का संभावित डुप्लिकेट (http://stackoverflow.com/questions/18180763/set-difference-for-pandas) – AKS

+0

@ 176 कोडिंग कृपया अपने वास्तविक डेटासेट पर हमारे उत्तरों का समय दें - यह मेरे लिए दिलचस्प है सबसे तेज़/ – knagaev

उत्तर

9

समाधान

उपयोग pd.concat द्वारा drop_duplicates(keep=False)

pd.concat([df1, df2, df2]).drop_duplicates(keep=False) 

पीछा किया ऐसा लगता है कि

pd.concat

तरह
a b 
1 3 4 

स्पष्टीकरण कहते हैं एक जोड़कर दो DataFrame एक साथ है दूसरे के ठीक बाद। यदि कोई ओवरलैप है, तो इसे drop_duplicates विधि द्वारा कैप्चर किया जाएगा। हालांकि, डिफ़ॉल्ट रूप से drop_duplicates पहले अवलोकन को छोड़ देता है और हर दूसरे अवलोकन को हटा देता है। इस मामले में, हम चाहते हैं कि प्रत्येक डुप्लिकेट हटा दिया जाए। इसलिए, keep=False पैरामीटर जो वास्तव में करता है।

बार-बार df2 पर एक विशेष नोट। df2 में किसी भी पंक्ति के साथ df2df1 में डुप्लिकेट नहीं माना जाएगा और यह रहेगा। यह समाधान केवल df2 के साथ ही काम करता है जब df2df1 का सबसेट है। हालांकि, अगर हम दो बार df2 को संगत करते हैं, तो यह एक डुप्लिकेट होने की गारंटी है और बाद में इसे हटा दिया जाएगा।

+0

thx है, यह काम करता है, और हम 'pd.concat (df1, df2) .drop_duplicates (keep = False)' या 'df1.append (df2) .drop_duplicates (रखें = गलत)' – 176coding

+0

@ 176 कोडिंग का उपयोग कर सकते हैं यह आपके प्रश्न का उत्तर देता है। यदि नहीं, तो मुझे बताएं कि अनुत्तरित क्या रहता है और मैं इसे संबोधित करने के लिए अपनी पूरी कोशिश करूंगा। – piRSquared

+1

@piRSquared आपका उत्तर सही नहीं है - आपने सममित अंतर बनाया है, अंतर नहीं (सरल)। – knagaev

0

एक सेट तर्क दृष्टिकोण। df1 और df2 की पंक्तियों को सेट में बदलें। फिर नए DataFrame

idx1 = set(df1.set_index(['a', 'b']).index) 
idx2 = set(df2.set_index(['a', 'b']).index) 

pd.DataFrame(list(idx1 - idx2), columns=df1.columns) 

    a b 
0 3 4 
0

एक मास्किंग दृष्टिकोण

df1[df1.apply(lambda x: x.values.tolist() not in df2.values.tolist(), axis=1)] 

    a b 
1 3 4 
+0

को '.olistist() 'की आवश्यकता नहीं है। – Stefan

0

मेरे मर्ज DF1 और सवाल से df2 साथ शॉट को परिभाषित करने के set घटाव का उपयोग करें।

का उपयोग करते हुए 'सूचक' पैरामीटर

In [74]: df1.loc[pd.merge(df1, df2, on=['a','b'], how='left', indicator=True)['_merge'] == 'left_only'] 
Out[74]: 
    a b 
1 3 4 
+0

क्या हो रहा है इसका एक स्पष्टीकरण यह एक अमीर जवाब देगा। आपने उल्लेख किया है कि इस विधि की सफलता की कुंजी 'संकेतक' पैरामीटर है, और इसे सही करने के लिए सेटिंग प्रत्येक पंक्ति में स्थान जानकारी जोड़ती है, जिसे आपका समाधान फ़िल्टर करने के लिए अंतिम चरण में उपयोग करता है, केवल पंक्तियों को रखने के लिए जो केवल बाएं डेटा में दिखाई देते हैं फ्रेम (सूचक == 'left_only')। – Dannid

1

आप .duplicated है, जो काफी अर्थपूर्ण होने का लाभ है का उपयोग कर सकते हैं:

%%timeit 
combined = df1.append(df2) 
combined[~combined.duplicated(keep=False)] 

1000 loops, best of 3: 875 µs per loop 

तुलना के लिए:

%timeit df1.loc[pd.merge(df1, df2, on=['a','b'], how='left', indicator=True)['_merge'] == 'left_only'] 

100 loops, best of 3: 4.57 ms per loop 


%timeit pd.concat([df1, df2, df2]).drop_duplicates(keep=False) 

1000 loops, best of 3: 987 µs per loop 


%timeit df2[df2.apply(lambda x: x.value not in df2.values, axis=1)] 

1000 loops, best of 3: 546 µs per loop 

संक्षेप में, np.array तुलना का उपयोग सबसे तेज़ है। वहां .tolist() की आवश्यकता नहीं है।

संबंधित मुद्दे