পাইথন পান্ডাস: কলাম বি এর সর্বোচ্চ মান দিয়ে সারি রেখে কলাম A দ্বারা সদৃশগুলি সরিয়ে ফেলুন


161

আমার কলাম ক এ পুনরাবৃত্ত মানগুলির সাথে একটি ডেটাফ্রেম রয়েছে I

আমার স্নাতকের:

A B
1 10
1 20
2 30
2 40
3 10

এটিতে পরিণত হওয়া উচিত:

A B
1 20
2 40
3 10

ডুপ্লিকেটগুলি ফেলে দেওয়ার জন্য ওয়েস কিছু দুর্দান্ত কার্যকারিতা যুক্ত করেছে: http://wesmckinney.com/blog/?p=340 । তবে এএএএফআইসিটি, এটি হুবহু নকলের জন্য তৈরি করা হয়েছে, সুতরাং কোন সারিগুলি রাখা হবে তা নির্বাচনের মানদণ্ডের কোনও উল্লেখ নেই।

আমি অনুমান করছি এটি করার সম্ভবত একটি সহজ উপায় --- ডুপ্লিকেটগুলি নামানোর আগে ডেটাফ্রেমকে বাছাই করার মতো সহজ --- তবে আমি গ্রুপবাইয়ের অভ্যন্তরীণ যুক্তিটি এটিকে বের করার পক্ষে যথেষ্ট জানি না। কোনও পরামর্শ?


1
নোট করুন যে প্রশ্নের URL টি EOL প্রদর্শিত হবে।
ডেভএল

একটি প্রতিমা ও পারফরম্যান্স উপায়ে, নীচের এই সমাধানটি দেখুন
টেড পেট্রো

উত্তর:


194

এটি শেষ লাগে। যদিও সর্বাধিক নয়:

In [10]: df.drop_duplicates(subset='A', keep="last")
Out[10]: 
   A   B
1  1  20
3  2  40
4  3  10

আপনি এর মতো কিছু করতে পারেন:

In [12]: df.groupby('A', group_keys=False).apply(lambda x: x.loc[x.B.idxmax()])
Out[12]: 
   A   B
A       
1  1  20
2  2  40
3  3  10

12
ছোট নোট: দ্য colsএবং take_lastপরামিতি মূল্যমান হ্রাস করা হয় এবং দ্বারা প্রতিস্থাপিত করা হয়েছে subsetএবং keepপ্যারামিটার। pandas.pydata.org/pandas-docs/version/0.17.1/gerenated/…
জেজামন

যেমন @ জিজামন বলেছেন,FutureWarning: the take_last=True keyword is deprecated, use keep='last' instead
অশান্তি_রোস্টার

1
ব্যবহার না করার কোনও কারণ আছে df.sort_values(by=['B']).drop_duplicates(subset=['A'], keep='last')? আমি বোঝাতে চাইছি এই সাজানো_মূল্যগুলি আমার কাছে নিরাপদ বলে মনে হচ্ছে তবে এটি আসলে হয় কিনা আমার কোনও ধারণা নেই।
লিটল ববি টেবিলগুলি

4
এই উত্তরটি এখন অপ্রচলিত। নীচে @ টেড পেট্রোর উত্তর দেখুন।
cxrodgers

আপনি যদি এই কোডটি কিন্তু একটির বেশি কলামের ক্ষেত্রে ব্যবহার করতে চান তাহলে group_by, আপনি যোগ করতে পারেন .reset_index(drop=True) df.groupby(['A','C'], group_keys=False).apply(lambda x: x.ix[x.B.idxmax()]).reset_index(drop=True)এই তার ডিফল্ট মান একটি Multindex হবে যেমন সূচক পুনরায় সেট করবে থেকে compsed 'A'এবং'C'
Hamri সাঈদ

79

শীর্ষের উত্তরটি খুব বেশি কাজ করছে এবং বড় ডেটা সেটগুলির জন্য খুব ধীর বলে মনে হচ্ছে। applyধীর এবং এটি সম্ভব হলে এড়ানো উচিত। ixঅবচয় করা হয় এবং পাশাপাশি এড়ানো উচিত।

df.sort_values('B', ascending=False).drop_duplicates('A').sort_index()

   A   B
1  1  20
3  2  40
4  3  10

অথবা কেবলমাত্র সমস্ত অন্যান্য কলাম দ্বারা গ্রুপ করুন এবং আপনার প্রয়োজনীয় কলামটি সর্বাধিক গ্রহণ করুন। df.groupby('A', as_index=False).max()


1
এটি আসলে একটি ক্লিভার পদ্ধতির। আমি ভাবছিলাম যে lambaড্রপ করার সময় কিছু ফাংশন ব্যবহার করে এটি সাধারণীকরণ করা যায় কিনা । উদাহরণস্বরূপ, আমি কীভাবে কেবলমাত্র সেইগুলি সদৃশ মানগুলির গড় বলার চেয়ে কম মান বাদ দিতে পারি।
ডেক্সটার

15

সহজ সমাধান:

একটি কলামের ভিত্তিতে সদৃশগুলি ফেলে দিতে:

df = df.drop_duplicates('column_name', keep='last')

একাধিক কলামের ভিত্তিতে সদৃশগুলি ফেলে দিতে:

df = df.drop_duplicates(['col_name1','col_name2','col_name3'], keep='last')

1
সব থেকে ভালো সমাধান. ধন্যবাদ।
ফ্লাভিও

সাহায্য করে আনন্দ পেলাম. @ ফ্লাভিও
গিল বাগজিও

আমার ডেটা ফ্রেমে 10 টি কলাম রয়েছে এবং আমি তিনটি কলাম থেকে নকল মুছতে এই কোডটি ব্যবহার করেছি। তবে এটি অন্যান্য কলামগুলি থেকে সারিগুলি মুছে ফেলেছে। ডুপ্লিকেটগুলি কেবলমাত্র 4 টি শেষ কলামের জন্য মুছার কোনও উপায় আছে?
সোফিয়া

2
তবে ওপি কলাম বিতে সর্বোচ্চ মান রাখতে চায় you তবে তারপরে এটি মূলত টেড পেট্রোয়ের উত্তর।
টিপিম্ম

7

এটা চেষ্টা কর:

df.groupby(['A']).max()

1
আসল ডাটাফ্রেমের মতো দেখতে এটির পুনর্নির্মাণের সেরা প্রতিমাটি কি জানেন? যখন আপনি আমাকে নিনজা করতেন তখন আমি তা বোঝার চেষ্টা করছিলাম। : ^)
ডিএসএম

4
ঝরঝরে। যদি ডেটাফ্রেমে আরও কলাম থাকে (যেমন, সি, ডি, ই)? সর্বাধিক ক্ষেত্রে সেই ক্ষেত্রে কাজ করছে বলে মনে হচ্ছে না, কারণ আমাদের উল্লেখ করতে হবে যে বি একমাত্র কলাম যা সর্বাধিক করা দরকার।
আবে

1
@ ডিএসএম মূল প্রশ্নের লিঙ্কটি পরীক্ষা করুন। গোষ্ঠীযুক্ত ডেটা ফ্রেমের পুনর্নির্মাণের জন্য কিছু কোড রয়েছে।
আবে

5

আমি প্রথমে কলাম বি নামার সাথে সাথে ডেটাফ্রেমকে সাজিয়ে রাখব, তারপরে কলাম এ এর ​​জন্য সদৃশগুলি ফেলে রেখে প্রথমে রাখব

df = df.sort_values(by='B', ascending=False)
df = df.drop_duplicates(subset='A', keep="first")

কোন গ্রুপবিহীন



1

আমি মনে করি আপনার ক্ষেত্রে সত্যিই একটি গ্রুপবিয়ের দরকার নেই। আমি আপনার বি কলামটি অবতরণ করে সাজিয়ে দেব, তারপরে কলাম এ-তে সদৃশগুলি ফেলে দিন এবং আপনি চাইলে আপনার মতো একটি নতুন সুন্দর এবং পরিষ্কার সূচকও থাকতে পারে:

df.sort_values('B', ascending=False).drop_duplicates('A').sort_index().reset_index(drop=True)

এটি অন্যান্য পোস্টের তুলনায় কীভাবে আলাদা?
DJK

1

এখানে ভাগ করার মতো যে সমস্যাগুলি সমাধান করতে হয়েছিল সেগুলি এখানে সমাধান করার জন্য এখানে ছিল: প্রতিটি অনন্য স্ট্রিংয়ের জন্য columnAআমি সর্বাধিক সাধারণ সম্পর্কিত স্ট্রিংটি খুঁজতে চেয়েছিলাম columnB

df.groupby('columnA').agg({'columnB': lambda x: x.mode().any()}).reset_index()

.any()এক পছন্দ মোডের জন্য টাই আছে কিনা। (নোট করুন যে .any()একটি সিরিজ ব্যবহার করেint এস সেগুলির মধ্যে একটি বাছাই না করে একটি বুলিয়ান দেয়))

মূল প্রশ্নের জন্য, সম্পর্কিত পদ্ধতির এটিকে সহজতর করে

df.groupby('columnA').columnB.agg('max').reset_index()


0

ইতিমধ্যে দেওয়া পোস্টগুলিতে প্রশ্নের উত্তর দেওয়ার সময়, আমি কলামের নাম যুক্ত করে একটি ছোট পরিবর্তন করেছি যার উপর আরও ভাল কোড পঠনযোগ্যতার জন্য সর্বোচ্চ () ফাংশন প্রয়োগ করা হয়।

df.groupby('A', as_index=False)['B'].max()

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

0

এটি করার সহজতম উপায়:

# First you need to sort this DF as Column A as ascending and column B as descending 
# Then you can drop the duplicate values in A column 
# Optional - you can reset the index and get the nice data frame again
# I'm going to show you all in one step. 

d = {'A': [1,1,2,3,1,2,3,1], 'B': [30, 40,50,42,38,30,25,32]}
df = pd.DataFrame(data=d)
df

    A   B
0   1   30
1   1   40
2   2   50
3   3   42
4   1   38
5   2   30
6   3   25
7   1   32


df = df.sort_values(['A','B'], ascending =[True,False]).drop_duplicates(['A']).reset_index(drop=True)

df

    A   B
0   1   40
1   2   50
2   3   42

-1

এটিও কাজ করে:

a=pd.DataFrame({'A':a.groupby('A')['B'].max().index,'B':a.groupby('A')       ['B'].max().values})

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

-8

আমি আপনাকে পুরো উত্তর দিতে যাচ্ছি না (আমি মনে করি না আপনি যেভাবেই পার্সিং এবং ফাইলটি লেখার জন্য লিখেছেন), তবে একটি মূল ইঙ্গিতটি যথেষ্ট হবে: পাইথনের set()ফাংশনটি ব্যবহার করুন , এবং তারপরে sorted()বা এর সাথে .sort()মিলিত .reverse():

>>> a=sorted(set([10,60,30,10,50,20,60,50,60,10,30]))
>>> a
[10, 20, 30, 50, 60]
>>> a.reverse()
>>> a
[60, 50, 30, 20, 10]

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

দুঃখিত, আমি এই নির্দিষ্ট পরিস্থিতি সম্পর্কে খুব বেশি জানি না, তাই এটি হতে পারে যে আমার জেনেরিক উত্তরটি আপনার সমস্যার জন্য খুব দক্ষ হিসাবে দেখাবে না।
আবরণিল দাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.