আমার দুটি ডেটা ফ্রেম 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এবং df23 সম্ভব ধরণের শ্রেণীবিভক্ত: "left_only", "right_only" বা "উভয়"।
কলামগুলির জন্য, এটি ব্যবহার করে দেখুন:
set(df1.columns).symmetric_difference(df2.columns)
mergeসঙ্গে indicator=Trueদেওয়া ক্ষেত্র দ্বারা dataframes তুলনা জন্য আপনি ক্লাসিক সমাধান।
গৃহীত উত্তর 1 পদ্ধতিটি ভিতরে এনএএনএস সহ ডেটা ফ্রেমের জন্য কাজ করবে না 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)
ঠিক আছে, আমি খুঁজে পেয়েছি সর্বোচ্চ ভোটের জবাবটিতে ইতিমধ্যে আমি যা আবিষ্কার করেছি তা রয়েছে Y হ্যাঁ, আমরা কেবল এই কোডটি এই শর্তে ব্যবহার করতে পারি যে প্রতি দুটি ডিএফ-তে কোনও সদৃশ নেই।
আমার কাছে একটি জটিল পদ্ধতি আছে method প্রথমটি আমরা প্রশ্নের দ্বারা প্রদত্ত দুটি ডাটাফ্রেমের সূচী হিসাবে 'নাম' সেট করি ince আমাদের দুটি ডিএফ-তে একই 'নাম' রয়েছে, তবে আমরা কেবল 'ছোট' ডিএফ এর সূচককে 'বড়' ডিএফ থেকে ফেলে দিতে পারি । কোডটি এখানে।
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)
সুন্দর @ লিয়াংলির সমাধানের সামান্য প্রকরণের জন্য যা বিদ্যমান ডেটাফ্রেমগুলির সূচি পরিবর্তন করতে হবে না:
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
স্বীকৃত উত্তর ছাড়াও, আমি আরও একটি আরও বিস্তৃত সমাধান প্রস্তাব করতে চাই যা কোনও / এর সাথে দুটি ডেফ্রেমের 2D সেট পার্থক্য খুঁজে পেতে পারে (তারা উভয় ডেট্রামের সাথে একযোগে মিলবে না)। এছাড়াও পদ্ধতি ডেটাফ্রেমের তুলনার জন্য উপাদানগুলির জন্য সহনশীলতা সেটআপ করতে দেয় (এটি ব্যবহার করে )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
পূর্বেই উল্লেখ করা হয়েছে এখানে যে
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)