পান্ডারা সারি পান যা অন্য ডেটাফ্রেমে নেই


228

আমার দুটি পান্ডাস ডেটা ফ্রেম রয়েছে যার কয়েকটি সারি প্রচলিত রয়েছে।

ধরুন ডেটাফ্রেম 2 হ'ল ডেটা ফ্রেম 1-এর একটি উপসেট।

আমি ডেটাফ্রেম 2 এর সারিগুলি কীভাবে পেতে পারি যা ডেটাফ্রেম 2 এ নেই?

df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]}) 
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})

1
@ টেডপেট্রো আপনার দেওয়া উত্তরটি কীভাবে সঠিক তা আমি দেখতে ব্যর্থ। আমার কাছে যদি দুটি ডেটাফ্রেম থাকে যার মধ্যে একটি অন্যটির উপসেট হয় তবে আমাকে সাবসেটে থাকা সমস্ত সারি সরিয়ে ফেলতে হবে। আমি নকলগুলি সরাতে চাই না। আমি পুরোপুরি সাবসেটটি সরাতে চাই।
জুকবক্স

উত্তর:


173

একটি পদ্ধতি হ'ল উভয় ডিএফএসের অভ্যন্তরীণ মার্জ ফর্মের ফলাফল সংরক্ষণ করা হবে, তবে যখন একটি কলামের মানগুলি সাধারণ না হয় তখন আমরা কেবল সারিগুলি নির্বাচন করতে পারি:

In [119]:

common = df1.merge(df2,on=['col1','col2'])
print(common)
df1[(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))]
   col1  col2
0     1    10
1     2    11
2     3    12
Out[119]:
   col1  col2
3     4    13
4     5    14

সম্পাদনা

আপনার সন্ধানের মতো অন্য একটি পদ্ধতি হ'ল ব্যবহার করা isinযা NaNসারি তৈরি করবে যা আপনি ফেলে দিতে পারেন:

In [138]:

df1[~df1.isin(df2)].dropna()
Out[138]:
   col1  col2
3     4    13
4     5    14

তবে যদি df2 একই পদ্ধতিতে সারিগুলি শুরু না করে তবে এটি কাজ করবে না:

df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11, 12,13]})

সম্পূর্ণ ডিএফ উত্পাদন করবে:

In [140]:

df1[~df1.isin(df2)].dropna()
Out[140]:
   col1  col2
0     1    10
1     2    11
2     3    12
3     4    13
4     5    14

13
df1[~df1.isin(df2)].dropna(how = 'all')কৌশলটি মনে হচ্ছে। যাইহোক ধন্যবাদ - আপনার উত্তর আমাকে সমাধান খুঁজে পেতে সহায়তা করেছে।
সুন্দর জিনিসগুলি ভাবুন

5
নোট করুন যে ব্যবহারের isinজন্য উভয় ডিএফএস একই সারি মানের সাথে শুরু হওয়া প্রয়োজন উদাহরণস্বরূপ যদি df2 হয় df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11,12, 13]})তবে আপনার পদ্ধতিটি কাজ করবে না
এডচুম

2
এই সমস্ত ints ভাসা রূপান্তরিত!
ক্রিস নিলসন

@ এডচাম, আমি যে ডেটা ব্যবহার করেছি সেটি হ'ল উপরের উদাহরণের সঠিক কোড। আমি সহজেই একটি নতুন জুপিটার নোটবুকে আপনার উদাহরণগুলি ফেলে দিয়েছি এবং ধাপে ধাপে কোডটি চালিয়েছি। সারি 3 থেকে গিয়েছিলাম 4 | 13থেকে 4.0 | 13.0উদাহরণস্বরূপ। এই পদক্ষেপের পরে এটি ঘটেছে:df1[~df1.isin(df2)].dropna()
ক্রিস নিলসন

3
@ সেরজেইখখারভ প্রায় 3 বছর আগে পোস্ট করা এই উত্তরটি যতক্ষণ না ওপি সম্পর্কিত এবং ঠিক ততই সঠিক ছিল এবং অন্য সমস্যাগুলির জন্য অন্য উত্তরটি আরও ভাল উত্তর এবং মূল প্রশ্নটির অংশ ছিল না এমন একটি বিস্তৃত সমস্যা পরিচালনা করে, এটি বলা ভুল নয় যে এটি উত্তরটি ভুল, নির্ধারিত হিসাবে সমস্যাটি দেওয়া সঠিক। অতিরিক্তভাবে কেউ ব্যাখ্যা ছাড়াই এটিকে হ্রাস করেছেন, এটি গ্রহণযোগ্য উত্তর হওয়ায় আমি খুব কমই করতে পারি, ওপি তাদের মন পরিবর্তন করেনি এবং এটি সঠিক করার জন্য আমি অন্য উত্তরটি ন্যাংবালাইজ করতে যাচ্ছি না ।
এডচুম

189

বর্তমানে নির্বাচিত সমাধানটি ভুল ফলাফল দেয়। সঠিকভাবে এই সমস্যা সমাধানের জন্য, আমরা থেকে একটি বাম-যোগ সম্পাদন করতে পারবেন df1করার df2, প্রথম মাত্র অনন্য সারি পেতে নিশ্চিত যার ফলে df2

প্রথমত, আমাদের [3, 10] এর সাথে সারি যুক্ত করতে আসল ডেটাফ্রেমটি সংশোধন করতে হবে।

df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 
                           'col2' : [10, 11, 12, 13, 14, 10]}) 
df2 = pd.DataFrame(data = {'col1' : [1, 2, 3],
                           'col2' : [10, 11, 12]})

df1

   col1  col2
0     1    10
1     2    11
2     3    12
3     4    13
4     5    14
5     3    10

df2

   col1  col2
0     1    10
1     2    11
2     3    12

বাম-যোগটি সম্পাদন করুন, ডুপ্লিকেটগুলি মুছে ফেলুন df2যাতে প্রতিটি সারি df1ঠিক 1 সারির সাথে যোগ দেয় df2indicatorকোন অতিরিক্ত কলামটি ফিরে আসার জন্য প্যারামিটারটি ব্যবহার করুন এটি নির্দেশ করে যে সারিটি সারণিটি ছিল।

df_all = df1.merge(df2.drop_duplicates(), on=['col1','col2'], 
                   how='left', indicator=True)
df_all

   col1  col2     _merge
0     1    10       both
1     2    11       both
2     3    12       both
3     4    13  left_only
4     5    14  left_only
5     3    10  left_only

একটি বুলিয়ান শর্ত তৈরি করুন:

df_all['_merge'] == 'left_only'

0    False
1    False
2    False
3     True
4     True
5     True
Name: _merge, dtype: bool

অন্যান্য সমাধান কেন ভুল

কয়েকটি সমাধান একই ভুল করে - তারা কেবলমাত্র প্রতিটি কলামে প্রতিটি মান এক সাথে একই সারিতে নয় স্বাধীনভাবে তা যাচাই করে। শেষ সারিটি যুক্ত করা, যা অনন্য তবে এতে দুটি কলামের মান df2ভুল থেকে প্রকাশ করে:

common = df1.merge(df2,on=['col1','col2'])
(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))
0    False
1    False
2    False
3     True
4     True
5    False
dtype: bool

এই সমাধান একই ভুল ফলাফল পায়:

df1.isin(df2.to_dict('l')).all(1)

2
তবে, আমি মনে করি, তারা ধরেই নিচ্ছিল যে কল 1 একটি সূচক হিসাবে অনন্য (প্রশ্নে উল্লিখিত নয়, তবে সুস্পষ্ট)। সুতরাং, যদি কোল 1 এর একই মানের জন্য কল 2 এর দুটি মান থাকে না এমন ক্ষেত্রে কখনও না ঘটে (দুটি কোল 1 = 3 সারি থাকতে পারে না) উপরের উত্তরগুলি সঠিক correct
পাশুতে

14
এটি অবশ্যই সুস্পষ্ট নয়, সুতরাং আপনার বক্তব্য অবৈধ। আমার সমাধান আরও কিছু ক্ষেত্রে সাধারণীকরণ করে।
টেড পেট্রো

প্রশ্ন, বুলিয়ান অ্যারের পরিবর্তে কোনও স্লাইস তৈরি করা সহজ হবে না? যেহেতু উদ্দেশ্যটি সারিগুলি পাওয়া।
মাতাসাস রোমো

5
df_all[df_all['_merge'] == 'left_only']ফলাফলগুলি সহ একটি ডিএফ ব্যবহার করুন
gies0r

77

ধরে নিই যে সূচীগুলি ডেটাফ্রেমে সামঞ্জস্যপূর্ণ (প্রকৃত মূল্য মান বিবেচনায় নিচ্ছে না):

df1[~df1.index.isin(df2.index)]

1
@ ক্রিস্নিলসন শর্তটিকে অস্বীকার করছেন। সুতরাং এই উদাহরণে এর অর্থ হল "সারিগুলি নেওয়া df1যা থেকে সূচিগুলি অন্তর্ভুক্ত নয় df2.index"। প্রত্যাখ্যানের বিষয়ে আরও: স্ট্যাকওভারফ্লো.com / q / 19960077 / 304209 (আশ্চর্যজনকভাবে, আমি পান্ডাস ডক্সে টিলডির কোনও উল্লেখ খুঁজে পাইনি)।
ডেনিস গোলোমাজভ

Dfs একই দৈর্ঘ্য হতে হবে বলে মনে হচ্ছে, না? আমি পেয়ে যাচ্ছিValueError: Item wrong length x instead of y.
14:48

@Wordferwise না, তারা না। মাস্কটির দৈর্ঘ্য df1 এবং এটি df1 তেও প্রয়োগ করা হয়। আপনি আপনার উদাহরণ প্রদান করতে পারেন?
ডেনিস গোলোমাজভ

আইটেমের দৈর্ঘ্যের ইস্যুটি সংশোধন করার জন্য আপনাকে .loc যুক্ত করতে হবে
মোরেনো

13

ইতিমধ্যে ইঙ্গিত হিসাবে, ইসিনের একটি ম্যাচের জন্য কলাম এবং সূচকগুলি একই হওয়া দরকার। যদি ম্যাচটি কেবল সারি সামগ্রীতে থাকে তবে উপস্থিত সারিগুলিকে ফিল্টার করার জন্য মুখোশ পাওয়ার একটি উপায় হ'ল সারিগুলিকে (মাল্টি) সূচীতে রূপান্তর করা:

In [77]: df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10]})
In [78]: df2 = pandas.DataFrame(data = {'col1' : [1, 3, 4], 'col2' : [10, 12, 13]})
In [79]: df1.loc[~df1.set_index(list(df1.columns)).index.isin(df2.set_index(list(df2.columns)).index)]
Out[79]:
   col1  col2
1     2    11
4     5    14
5     3    10

যদি সূচকটি বিবেচনায় নেওয়া উচিত, সেট_ইন্ডেক্সে বিদ্যমান সূচীতে কলাম যুক্ত করতে মূল যুক্তি যুক্ত রয়েছে। যদি কলামগুলি একসাথে না থাকে, তথ্যের সারিবদ্ধকরণের জন্য কলামের বিশদকরণের সাথে তালিকার (df.colالms) প্রতিস্থাপন করা যেতে পারে।

pandas.MultiIndex.from_tuples(df<N>.to_records(index = False).tolist())

সূচকগুলি তৈরি করতে বিকল্পভাবে ব্যবহার করা যেতে পারে, যদিও আমি সন্দেহ করি এটি আরও কার্যকর।


@ Dev_123 শুরুতে ~ সরান। কোরটি ডিএফ 1-এ সারিগুলি ডিএফ 2-এ ঘটে কিনা তার একটি সূক্ষ্ম তালিকা তৈরি করা হয়, সুতরাং df1-এ থাকা সারিগুলি df1-র তুলনায় স্বতন্ত্র নয়, d df1-এ সারিগুলি df2-তে ঘটে না কিনা তার একটি প্রাক্কলিত তালিকায় এটি উপেক্ষা করে।
রুন লিঙ্গসয়ে

11

ধরুন আপনার দুটি ডেটাফ্রেম রয়েছে, df_1 এবং df_2 একাধিক ক্ষেত্র রয়েছে (কলাম_নাম) এবং আপনি কেবলমাত্র df_1 এ কেবলমাত্র কিছু ক্ষেত্রের (যেমন ক্ষেত্র_ x, ক্ষেত্র_ y) ভিত্তিতে df_2 এ নেই এমন প্রবেশিকাগুলি সন্ধান করতে চান, নিম্নলিখিত পদক্ষেপগুলি অনুসরণ করুন।

পদক্ষেপ 1. একটি কলাম কী 1 এবং কী 2 যথাক্রমে df_1 এবং df_2 এ যুক্ত করুন।

পদক্ষেপ 2. নীচে প্রদর্শিত হিসাবে ডেটা ফ্রেম মার্জ। ফিল্ড_এক্স এবং ফিল্ড_ই আমাদের কাঙ্ক্ষিত কলাম।

স্টিপি 3। কেবলমাত্র df_1 থেকে সারিগুলি নির্বাচন করুন যেখানে কী 1 কী 2 এর সমান নয়।

ধাপ 4. ড্রপ কী 1 এবং কী 2।

এই পদ্ধতিটি আপনার সমস্যার সমাধান করবে এবং বড় ডেটা সেট সহ দ্রুত কাজ করবে। আমি এটির জন্য 10,000,000 সারি ডেটা ফ্রেমগুলির জন্য চেষ্টা করেছি।

df_1['key1'] = 1
df_2['key2'] = 1
df_1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'left')
df_1 = df_1[~(df_1.key2 == df_1.key1)]
df_1 = df_1.drop(['key1','key2'], axis=1)

তিনি প্রযুক্তিগতভাবে যা চান তা আমি মনে করি না - তিনি জানতে চান কোন সারিটি কোন ডিএফ-এর সাথে অনন্য ছিল। তবে, আমি মনে করি যে এই সমাধানটি সারিগুলির একটি ডিএফ প্রদান করে যা হয় প্রথম ডিএফ বা দ্বিতীয় ডিএফ থেকে অনন্য ছিল।
লেজিট স্ট্যাক

6

কিছুটা দেরি করলেও এটি পিডি.মেজারের "সূচক" পরামিতিটি পরীক্ষা করার পক্ষে উপযুক্ত।

উদাহরণস্বরূপ এই অন্যান্য প্রশ্নটি দেখুন: পান্ডস ডেটা ফ্রেমগুলির সাথে তুলনা করুন এবং প্রথমটি থেকে নিখোঁজ থাকা সারিগুলি ফেরৎ দিন


হ্যাঁ! এছাড়াও এখানে: স্ট্যাকওভারফ্লো.com
ড্যান

3

আপনি এটি আইসিন (ডিক্ট) পদ্ধতি ব্যবহার করে করতে পারেন :

In [74]: df1[~df1.isin(df2.to_dict('l')).all(1)]
Out[74]:
   col1  col2
3     4    13
4     5    14

ব্যাখ্যা:

In [75]: df2.to_dict('l')
Out[75]: {'col1': [1, 2, 3], 'col2': [10, 11, 12]}

In [76]: df1.isin(df2.to_dict('l'))
Out[76]:
    col1   col2
0   True   True
1   True   True
2   True   True
3  False  False
4  False  False

In [77]: df1.isin(df2.to_dict('l')).all(1)
Out[77]:
0     True
1     True
2     True
3    False
4    False
dtype: bool

এটি ভুল ফলাফল উত্পন্ন করে। আমার ব্যাখ্যা নীচে দেখুন।
টেড পেট্রো

2

এছাড়াও আপনি CONCAT করতে df1, df2:

x = pd.concat([df1, df2])

এবং তারপরে সমস্ত অনুলিপি মুছে ফেলুন:

y = x.drop_duplicates(keep=False, inplace=False)

স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম: আপনি যদি কোড, এক্সএমএল বা ডেটা নমুনাগুলি পোস্ট করেন তবে অনুগ্রহ করে টেক্সট সম্পাদকের সেই লাইনগুলি হাইলাইট করুন এবং সম্পাদনা সরঞ্জামদণ্ডে "কোড স্যাম্পল" বোতামটি ({click) ক্লিক করুন বা আপনার কীবোর্ডের সিআরটিএল + কে ব্যবহার করে সুন্দর বিন্যাস করুন এবং সিনট্যাক্স এটি হাইলাইট!
হোয়াটপয়েন্টে

4
এটি কেবলমাত্র ডিএফ 1 এ থাকা ডেটা নয়, উভয় সেটে থাকা সমস্ত ডেটা ফেরত দেবে।
জেমি মার্শাল

1

এটি সম্পর্কে:

df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 
                               'col2' : [10, 11, 12, 13, 14]}) 
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 
                               'col2' : [10, 11, 12]})
records_df2 = set([tuple(row) for row in df2.values])
in_df2_mask = np.array([tuple(row) in records_df2 for row in df1.values])
result = df1[~in_df2_mask]

1

এটি সমাধানের আরেকটি উপায় এখানে:

df1[~df1.index.isin(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]

বা:

df1.loc[df1.index.difference(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]

0

আমার এটি করার পদ্ধতিতে একটি নতুন কলাম যুক্ত করা যা একটি ডেটাফ্রেমের জন্য স্বতন্ত্র এবং এটিতে প্রবেশ রাখতে হবে কিনা তা বেছে নিতে এটি ব্যবহার করে

df2[col3] = 1
df1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'outer')
df1['Empt'].fillna(0, inplace=True)

এটি ডিএফ 1 এর প্রতিটি প্রবেশের একটি কোড রয়েছে - 0 এটি df1 এর জন্য অনন্য, 1 যদি এটি উভয় ডেটা ফ্রেমে থাকে। তারপরে আপনি এটি যা চান তা সীমাবদ্ধ করতে এটি ব্যবহার করুন

answer = nonuni[nonuni['Empt'] == 0]

0
মার্জ ফাংশনটি ব্যবহার করে বিচিত্র সারিগুলি বের করুন
df = df.merge(same.drop_duplicates(), on=['col1','col2'], 
               how='left', indicator=True)
সিএসভিতে ভিন্নতম সারিগুলি সংরক্ষণ করুন
df[df['_merge'] == 'left_only'].to_csv('output.csv')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.