मेरे पास दो डेटा फ़्रेम df1 और df2 हैं, जहाँ df2 df1 का सबसेट है। मुझे एक नया डेटा फ़्रेम (df3) कैसे मिलेगा, जो दो डेटा फ़्रेमों के बीच का अंतर है?
दूसरे शब्द में, एक डेटा फ्रेम जिसमें df1 में सभी पंक्तियाँ / स्तंभ हैं जो df2 में नहीं हैं?
जवाबों:
का उपयोग करके drop_duplicates
pd.concat([df1,df2]).drop_duplicates(keep=False)
Update :
Above method only working for those dataframes they do not have duplicate itself, For example
df1=pd.DataFrame({'A':[1,2,3,3],'B':[2,3,4,4]})
df2=pd.DataFrame({'A':[1],'B':[2]})
यह नीचे की तरह आउटपुट देगा, जो गलत है
गलत आउटपुट:
pd.concat([df1, df2]).drop_duplicates(keep=False)
Out[655]:
A B
1 2 3
सही आउटपुट
Out[656]:
A B
1 2 3
2 3 4
3 3 4
कैसे प्राप्त करें?
विधि 1: का उपयोग isinकरtuple
df1[~df1.apply(tuple,1).isin(df2.apply(tuple,1))]
Out[657]:
A B
1 2 3
2 3 4
3 3 4
विधि 2: के mergeसाथindicator
df1.merge(df2,indicator = True, how='left').loc[lambda x : x['_merge']!='both']
Out[421]:
A B _merge
1 2 3 left_only
2 3 4 left_only
3 3 4 left_only
pd.concat([df1,df2]).drop_duplicates(subset = ['col1','col2'], keep=False)
float(क्योंकि 12.00000000001 != 12) है तो यह अनपेक्षित पंक्तियों के कारण हो सकता है । एक बेहतर अभ्यास दो डेटा फ़्रेमों में आईडी के सेट चौराहे को खोजने और उस पर आधारित अंतर प्राप्त करना है।
indicator=True) एक बहुत ही बहुमुखी और उपयोगी उपकरण है, मैं इसे इस उत्तर के शीर्ष पर देखना पसंद करूंगा, लेकिन 'बाहरी' नहीं 'के साथ' सभी 3 स्थितियों को कवर करने के लिए शामिल हो जाएगा।
पंक्तियों के लिए, यह कोशिश करें, जहां Nameसंयुक्त सूचकांक कॉलम है (कई सामान्य स्तंभों के लिए एक सूची हो सकती है, या निर्दिष्ट करें left_onऔर right_on):
m = df1.merge(df2, on='Name', how='outer', suffixes=['', '_'], indicator=True)
indicator=Trueके रूप में यह एक स्तंभ कहा जाता है कहते हैं सेटिंग उपयोगी होती है _merge, के बीच सभी परिवर्तन के साथ df1और df2, 3 संभव प्रकार में वर्गीकृत किया: "left_only", "right_only" या "दोनों"।
स्तंभों के लिए, यह आज़माएँ:
set(df1.columns).symmetric_difference(df2.columns)
mergeके साथ indicator=Trueदिए गए फ़ील्ड द्वारा डेटाफ़्रेम की तुलना करने के लिए क्लासिक समाधान है।
स्वीकृत उत्तर पद्धति 1, NaNs के साथ डेटा फ़्रेम के लिए अंदर काम नहीं करेगा, जैसा कि pd.np.nan != pd.np.nan। मुझे यकीन नहीं है कि यह सबसे अच्छा तरीका है, लेकिन इससे बचा जा सकता है
df1[~df1.astype(str).apply(tuple, 1).isin(df2.astype(str).apply(tuple, 1))]
edit2, मैंने इंडेक्स सेट करने की आवश्यकता के बिना एक नया समाधान निकाला
newdf=pd.concat([df1,df2]).drop_duplicates(keep=False)
ठीक है, मैंने पाया कि सबसे ज्यादा वोट का जवाब पहले से ही मेरे पास मौजूद है। हां, हम केवल इस कोड का उपयोग इस शर्त पर कर सकते हैं कि प्रत्येक दो dfs में कोई डुप्लिकेट नहीं है।
मेरे पास एक मुश्किल तरीका है। पहले हमने 'नाम' को प्रश्न द्वारा दिए गए दो डेटाफ्रेम के सूचकांक के रूप में सेट किया। चूंकि हमारे पास दो dfs में समान 'नाम' हैं, इसलिए हम 'छोटे' df के सूचकांक को 'बड़े' df से गिरा सकते हैं। यहाँ कोड है।
df1.set_index('Name',inplace=True)
df2.set_index('Name',inplace=True)
newdf=df1.drop(df2.index)
import pandas as pd
# given
df1 = pd.DataFrame({'Name':['John','Mike','Smith','Wale','Marry','Tom','Menda','Bolt','Yuswa',],
'Age':[23,45,12,34,27,44,28,39,40]})
df2 = pd.DataFrame({'Name':['John','Smith','Wale','Tom','Menda','Yuswa',],
'Age':[23,12,34,44,28,40]})
# find elements in df1 that are not in df2
df_1notin2 = df1[~(df1['Name'].isin(df2['Name']) & df1['Age'].isin(df2['Age']))].reset_index(drop=True)
# output:
print('df1\n', df1)
print('df2\n', df2)
print('df_1notin2\n', df_1notin2)
# df1
# Age Name
# 0 23 John
# 1 45 Mike
# 2 12 Smith
# 3 34 Wale
# 4 27 Marry
# 5 44 Tom
# 6 28 Menda
# 7 39 Bolt
# 8 40 Yuswa
# df2
# Age Name
# 0 23 John
# 1 12 Smith
# 2 34 Wale
# 3 44 Tom
# 4 28 Menda
# 5 40 Yuswa
# df_1notin2
# Age Name
# 0 45 Mike
# 1 27 Marry
# 2 39 Bolt
शायद समान या अलग कॉलम नामों के साथ एक सरल एक-लाइनर। तब भी काम किया जब df2 ['Name2'] में डुप्लिकेट मान शामिल थे।
newDf = df1.set_index('Name1')
.drop(df2['Name2'], errors='ignore')
.reset_index(drop=False)
df1[~df1.apply(tuple,1).isin(df2.apply(tuple,1))]
सही समाधान है, लेकिन अगर यह गलत आउटपुट का उत्पादन करेगा
df1=pd.DataFrame({'A':[1],'B':[2]})
df2=pd.DataFrame({'A':[1,2,3,3],'B':[2,3,4,4]})
उस मामले में उपरोक्त समाधान
खाली डेटाफ़्रेम देगा , इसके बजाय आपको concatप्रत्येक डेटाफ़्रेम से डुप्लिकेट को हटाने के बाद विधि का उपयोग करना चाहिए ।
उपयोग concate with drop_duplicates
df1=df1.drop_duplicates(keep="first")
df2=df2.drop_duplicates(keep="first")
pd.concat([df1,df2]).drop_duplicates(keep=False)
df1[~df1.apply(tuple,1).isin(df2.apply(tuple,1))]इस मामले में भी सही उत्तर है। यदि आप उन मानों को प्राप्त करना चाहते हैं जो या तो df1 या df2 में हैं, लेकिन दोनों में नहीं है, तो आपका सुझाया दृष्टिकोण सही है (मूल डेटाफ़्रेम से डुप्लिकेट को हटाने के कैविएट के साथ)।
अच्छा @ लिआंग्ली के समाधान की थोड़ी भिन्नता जिसे मौजूदा डेटाफ़्रेम के सूचकांक को बदलने की आवश्यकता नहीं है:
newdf = df1.drop(df1.join(df2.set_index('Name').index))
सूचकांक द्वारा अंतर खोजना। Df1 को मान लेना df2 का सबसेट है और सब्मिट करते समय इंडेक्स को आगे बढ़ाया जाता है
df1.loc[set(df1.index).symmetric_difference(set(df2.index))].dropna()
# Example
df1 = pd.DataFrame({"gender":np.random.choice(['m','f'],size=5), "subject":np.random.choice(["bio","phy","chem"],size=5)}, index = [1,2,3,4,5])
df2 = df1.loc[[1,3,5]]
df1
gender subject
1 f bio
2 m chem
3 f phy
4 m bio
5 f bio
df2
gender subject
1 f bio
3 f phy
5 f bio
df3 = df1.loc[set(df1.index).symmetric_difference(set(df2.index))].dropna()
df3
gender subject
2 m chem
4 m bio
स्वीकृत जवाब के अलावा, मैं एक और व्यापक समाधान का प्रस्ताव करना चाहूंगा जो कि किसी भी / के साथ दो डेटाफ्रेम के 2 डी सेट अंतर को पा सकता है (वे दोनों डेटामार्क के लिए मेल नहीं खा सकते हैं)। इसके अलावा विधि डेटाफ़्रेम तुलना के लिए तत्वों के लिए सहिष्णुता को स्थापित करने की अनुमति देती है (यह उपयोग करता हैindexcolumnsfloatnp.isclose )
import numpy as np
import pandas as pd
def get_dataframe_setdiff2d(df_new: pd.DataFrame,
df_old: pd.DataFrame,
rtol=1e-03, atol=1e-05) -> pd.DataFrame:
"""Returns set difference of two pandas DataFrames"""
union_index = np.union1d(df_new.index, df_old.index)
union_columns = np.union1d(df_new.columns, df_old.columns)
new = df_new.reindex(index=union_index, columns=union_columns)
old = df_old.reindex(index=union_index, columns=union_columns)
mask_diff = ~np.isclose(new, old, rtol, atol)
df_bool = pd.DataFrame(mask_diff, union_index, union_columns)
df_diff = pd.concat([new[df_bool].stack(),
old[df_bool].stack()], axis=1)
df_diff.columns = ["New", "Old"]
return df_diff
उदाहरण:
In [1]
df1 = pd.DataFrame({'A':[2,1,2],'C':[2,1,2]})
df2 = pd.DataFrame({'A':[1,1],'B':[1,1]})
print("df1:\n", df1, "\n")
print("df2:\n", df2, "\n")
diff = get_dataframe_setdiff2d(df1, df2)
print("diff:\n", diff, "\n")
Out [1]
df1:
A C
0 2 2
1 1 1
2 2 2
df2:
A B
0 1 1
1 1 1
diff:
New Old
0 A 2.0 1.0
B NaN 1.0
C 2.0 NaN
1 B NaN 1.0
C 1.0 NaN
2 A 2.0 NaN
C 2.0 NaN