पायथन पांडा: कॉलम A में उच्चतम मान वाली पंक्ति रखते हुए, कॉलम A द्वारा डुप्लिकेट निकालें


161

मेरे पास कॉलम ए में दोहराए जाने वाले मानों के साथ एक डेटाफ्रेम है। मैं डुप्लिकेट को ड्रॉप करना चाहता हूं, कॉलम बी में उच्चतम मूल्य के साथ पंक्ति रखते हुए।

तो यह:

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 । लेकिन AFAICT, इसे सटीक डुप्लिकेट के लिए डिज़ाइन किया गया है, इसलिए यह चुनने के लिए मापदंड का कोई उल्लेख नहीं है कि कौन सी पंक्तियों को रखा जाए।

मैं अनुमान लगा रहा हूं कि ऐसा करने का एक आसान तरीका है --- शायद डुप्लिकेट को छोड़ने से पहले डेटाफ्रेम को सॉर्ट करना जितना आसान है --- लेकिन मुझे यह पता लगाने के लिए ग्रुपबी के आंतरिक तर्क को अच्छी तरह से पता नहीं है। कोई सुझाव?


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/generated/…
Jezzamon

@Jezzamon कहते हैं,FutureWarning: the take_last=True keyword is deprecated, use keep='last' instead
tumultous_rooster

1
उपयोग न करने का कोई कारण है df.sort_values(by=['B']).drop_duplicates(subset=['A'], keep='last')? मेरा मतलब है कि यह Sort_values ​​मेरे लिए सुरक्षित लगता है, लेकिन मुझे नहीं पता कि यह वास्तव में है या नहीं।
लिटिल बॉबी टेबल्स

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)यह इंडेक्स को रीसेट कर देगा क्योंकि इसका डिफ़ॉल्ट मान एक मल्टीइन्डेक्स से बना होगा '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
लेकिन ओपी कॉलम बी में उच्चतम मूल्य रखना चाहता है। यदि आप पहले हल करते हैं तो यह काम कर सकता है। लेकिन फिर यह मूल रूप से टेड पेट्रो का जवाब है।
तेईपेम्म

7

इसे इस्तेमाल करे:

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

1
D'you को जानने के लिए सबसे अच्छा मुहावरा पता है यह मूल DataFrame जैसा दिखता है? मैं यह पता लगाने की कोशिश कर रहा था कि जब आप मुझे निंजा चाहेंगे। : ^)
DSM

4
साफ। क्या होगा यदि डेटाफ़्रेम में अधिक कॉलम (जैसे C, D, E) हों? मैक्स उस मामले में काम नहीं करता है, क्योंकि हमें यह निर्दिष्ट करने की आवश्यकता है कि बी एकमात्र स्तंभ है जिसे अधिकतम करने की आवश्यकता है।
अबे

1
@DSM मूल प्रश्न में लिंक की जाँच करें। समूहीकृत डेटाफ़्रेम को फिर से जोड़ने के लिए कुछ कोड है।
अबे

5

मैं पहले कॉलम बी के साथ डेटाफ्रेम छांटता हूं, फिर कॉलम ए के लिए डुप्लिकेट छोड़ता हूं और पहले रखता हूं

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

बिना किसी समूह के



1

मुझे लगता है कि आपके मामले में आपको वास्तव में एक ग्रुपबी की जरूरत नहीं है। मैं आपके B कॉलम को अवरोही क्रम से सॉर्ट करूँगा, फिर कॉलम A पर डुप्लिकेट को छोड़ दूंगा और यदि आप चाहते हैं कि आपके पास एक नया अच्छा और स्वच्छ सूचकांक भी हो सकता है:

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

यह अन्य पदों की तुलना में कैसे भिन्न है?
डीजेके

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()

कृपया अपने उत्तरों को थोड़ा और संदर्भ दें, यह समझाते हुए कि वे कैसे काम करते हैं और वे किसी प्रश्न के लिए पहले से उपलब्ध उत्तरों से बेहतर या पूरक क्यों हैं। यदि वे अतिरिक्त मूल्य प्रदान नहीं करते हैं, तो कृपया पुराने प्रश्नों पर अतिरिक्त उत्तर पोस्ट करने से बचें। अंत में, कृपया अपने कोड को इंडेंट करके कोड ब्लॉक के रूप में प्रारूपित करें।
WhoIsJack

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
हो सकता है कि मैं इस पर गलत हूं, लेकिन एक सेट के रूप में एक पांडा डेटाफ्रैम को फिर से तैयार करना, फिर इसे वापस परिवर्तित करना इस समस्या को हल करने के लिए एक बहुत ही अक्षम तरीका लगता है। मैं लॉग विश्लेषण कर रहा हूं, इसलिए मैं इसे कुछ बहुत बड़े डेटा सेटों पर लागू करूंगा।
अबे

क्षमा करें, मैं इस विशेष परिदृश्य के बारे में बहुत अधिक नहीं जानता, इसलिए यह हो सकता है कि मेरा सामान्य उत्तर आपकी समस्या के लिए बहुत अधिक कुशल नहीं होगा।
अभिनील दास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.