2012-03-24 16 views
15

मैं निम्नलिखित dataframe है:पांडा - किसी खास कॉलम एक और स्तंभ द्वारा अनुक्रमित का सबसे हाल ही मूल्य प्राप्त (एक विशेष कॉलम एक और स्तंभ द्वारा अनुक्रमित की अधिकतम मूल्य प्राप्त)

obj_id data_date value 
0 4  2011-11-01 59500  
1 2  2011-10-01 35200 
2 4  2010-07-31 24860 
3 1  2009-07-28 15860 
4 2  2008-10-15 200200 

मैं का एक सबसेट प्राप्त करना चाहते हैं यह डेटा इसलिए है कि मेरे पास प्रत्येक 'obj_id' के लिए सबसे हालिया (सबसे बड़ा 'data_date') 'value' है।

मैंने एक समाधान को एक साथ हैक किया है, लेकिन यह गंदा लगता है। मैं सोच रहा था कि किसी के पास बेहतर तरीका है या नहीं। मुझे यकीन है कि मुझे पांडा के माध्यम से ऐसा करने का कुछ आसान तरीका याद आना चाहिए।

मेरे विधि समूह के लिए अनिवार्य रूप से है, प्रकार, पुनः प्राप्त करेगा और इस प्रकार पुनः संयोजित:

row_arr = [] 
for grp, grp_df in df.groupby('obj_id'): 
    row_arr.append(dfg.sort('data_date', ascending = False)[:1].values[0]) 

df_new = DataFrame(row_arr, columns = ('obj_id', 'data_date', 'value')) 

उत्तर

2

aggregate() method GroupBy वस्तुओं पर एक ही चरण में एक GroupBy वस्तु से एक नया DataFrame बनाने के लिए इस्तेमाल किया जा सकता है। (मैं एक क्लीनर तरीका हालांकि एक DataFrame के पहले/अंतिम पंक्ति को निकालने के लिए के बारे में पता नहीं कर रहा हूँ।)

In [12]: df.groupby('obj_id').agg(lambda df: df.sort('data_date')[-1:].values[0]) 
Out[12]: 
     data_date value 
obj_id     
1  2009-07-28 15860 
2  2011-10-01 35200 
4  2011-11-01 59500 

आप अलग-अलग स्तंभों पर एकत्रीकरण प्रदर्शन कर सकते हैं, जिस स्थिति में समेकित फ़ंक्शन एक श्रृंखला वस्तु पर काम करता है ।

In [25]: df.groupby('obj_id')['value'].agg({'diff': lambda s: s.max() - s.min()}) 
Out[25]: 
      diff 
obj_id   
1   0 
2  165000 
4  34640 
4

मैं crewbum के जवाब पसंद है, शायद इस तेजी से होता है (क्षमा करें, अभी तक इस परीक्षण नहीं किया था, लेकिन मैं सब कुछ छँटाई से बचने):

df.groupby('obj_id').agg(lambda df: df.values[df['data_date'].values.argmax()]) 

यह numpys "argmax" समारोह का उपयोग करता है खोजने के लिए पंक्तिइंडेक्स जिसमें अधिकतम दिखाई देता है।

+0

मैं 24,735 पंक्तियों के साथ एक dataframe पर गति का परीक्षण किया, 16 समूहों (Btw: planethunter.org से डाटासेट) में बांटा और मिल गया 12.5 एमएस (argmax) 17.5 एमएस (प्रकार) के रूप में बनाम % समय का परिणाम। तो दोनों समाधान काफी तेज़ हैं :-) और मेरा डेटासेट बहुत छोटा लगता है ;-) – Maximilian

8

यदि "obj_id" की संख्या बहुत अधिक है तो आप संपूर्ण डेटाफ्रेम को सॉर्ट करना चाहते हैं और फिर अंतिम तत्व प्राप्त करने के लिए डुप्लीकेट छोड़ना चाहते हैं।

sorted = df.sort_index(by='data_date') 
result = sorted.drop_duplicates('obj_id', take_last=True).values 

यह तेजी से (खेद मैं इसे परीक्षण नहीं किया है) क्योंकि आप एक कस्टम agg समारोह है, जो धीमी है क्या करने के लिए जब वहाँ कुंजी की एक बड़ी संख्या है की जरूरत नहीं है होना चाहिए। आपको लगता है कि पूरे डेटा फ्रेम को सॉर्ट करना बदतर है, लेकिन पाइथन प्रकार में अभ्यास में तेज़ और देशी लूप धीमे होते हैं।

+0

यह एक आकर्षण काम करता है, अन्य उत्तरों में सभी के लिए मेरे पास समस्याएं थीं, और यह भी बहुत तेज थी। –

+0

यह पीडीफ़्रैंक द्वारा उत्तर की तुलना में मेरे लिए तीव्रता के क्रम से अधिक था। यह सवाल एसओ पर विभिन्न गानों में मौजूद है। मैं उन्हें सभी को इस जवाब में इंगित करूंगा। बस एक नोट 'फ्यूचरवार्निंग: take_last = True कीवर्ड बहिष्कृत है, बजाय =' last 'बजाय' का उपयोग करें। –

0

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

df = pd.DataFrame({ 
'CARD_NO': ['000', '001', '002', '002', '001', '111'], 
'DATE': ['2006-12-31 20:11:39','2006-12-27 20:11:53','2006-12-28 20:12:11','2006-12-28 20:12:13','2008-12-27 20:11:53','2006-12-30 20:11:39']}) 

print df 
df.groupby('CARD_NO').apply(lambda df:df['DATE'].values[df['DATE'].values.argmax()]) 

मूल

CARD_NO     DATE 
0  000 2006-12-31 20:11:39 
1  001 2006-12-27 20:11:53 
2  002 2006-12-28 20:12:11 
3  002 2006-12-28 20:12:13 
4  001 2008-12-27 20:11:53 
5  111 2006-12-30 20:11:39 

वापस किया गया dataframe:

CARD_NO 
000  2006-12-31 20:11:39 
001  2008-12-27 20:11:53 
002  2006-12-28 20:12:13 
111  2006-12-30 20:11:39 
12

यह एक और संभव समाधान है। मेरा मानना ​​है कि यह सबसे तेज़ है। के रूप में tommy.carstensen ने बताया कार्यों में से कुछ के बाद से

df.loc[df.groupby('obj_id').data_date.idxmax(),:] 
+2

यह एक अच्छा तरीका है जो इस और अन्य संदर्भों में मेरे लिए काम करता है। – alexbw

+0

अन्य अच्छे तरीकों की तुलना में एक अच्छा सामान्य समाधान बल्कि धीमा – josh

0

अपडेट कर रहा है thetainted1 का जवाब अब भविष्य में चेतावनियां हैं।यहां बताया गया है मेरे लिए काम किया है:

sorted = df.sort_values(by='data_date') 

result = sorted.drop_duplicates('obj_id', keep='last') 
संबंधित मुद्दे