2017-12-21 97 views
7

पायथन पांडस में, मेरे पास डेटाफ्रेम है। मैं इस डेटाफ्रेम को एक कॉलम से समूहित करता हूं और किसी कॉलम के अंतिम मान को किसी अन्य कॉलम की सभी पंक्तियों को असाइन करना चाहता हूं।पायथन पांडस: उस समूह की सभी प्रविष्टियों के लिए डेटाफ्रेम समूह का अंतिम मूल्य असाइन करें

मुझे पता है कि मैं इस आदेश से समूह के अंतिम पंक्ति का चयन करने में सक्षम हूँ:

import pandas as pd 

df = pd.DataFrame({'a': (1,1,2,3,3), 'b':(20,21,30,40,41)}) 
print(df) 
print("-") 
result = df.groupby('a').nth(-1) 
print(result) 

परिणाम:

a b 
0 1 20 
1 1 21 
2 2 30 
3 3 40 
4 3 41 
- 
    b 
a  
1 21 
2 30 
3 41 

यह कैसे इस आपरेशन के परिणाम आवंटित करने के लिए संभव हो जाएगा मूल डेटाफ्रेम पर वापस जाएं ताकि मेरे पास कुछ ऐसा हो:

a b b_new 
0 1 20 21 
1 1 21 21 
2 2 30 30 
3 3 40 41 
4 3 41 41 

उत्तर

4

का उपयोग करेंlast साथ:

df['b_new'] = df.groupby('a')['b'].transform('last') 

वैकल्पिक:

df['b_new'] = df.groupby('a')['b'].transform(lambda x: x.iat[-1]) 

print(df) 
    a b b_new 
0 1 20  21 
1 1 21  21 
2 2 30  30 
3 3 40  41 
4 3 41  41 

nth साथ और join समाधान:

df = df.join(df.groupby('a')['b'].nth(-1).rename('b_new'), 'a') 
print(df) 
    a b b_new 
0 1 20  21 
1 1 21  21 
2 2 30  30 
3 3 40  41 
4 3 41  41 

समय:

N = 10000 

df = pd.DataFrame({'a':np.random.randint(1000,size=N), 
        'b':np.random.randint(10000,size=N)}) 

#print (df) 


def f(df): 
    return df.join(df.groupby('a')['b'].nth(-1).rename('b_new'), 'a') 

#cᴏʟᴅsᴘᴇᴇᴅ1 
In [211]: %timeit df['b_new'] = df.a.map(df.groupby('a').b.nth(-1)) 
100 loops, best of 3: 3.57 ms per loop 

#cᴏʟᴅsᴘᴇᴇᴅ2 
In [212]: %timeit df['b_new'] = df.a.replace(df.groupby('a').b.nth(-1)) 
10 loops, best of 3: 71.3 ms per loop 

#jezrael1 
In [213]: %timeit df['b_new'] = df.groupby('a')['b'].transform('last') 
1000 loops, best of 3: 1.82 ms per loop 

#jezrael2 
In [214]: %timeit df['b_new'] = df.groupby('a')['b'].transform(lambda x: x.iat[-1]) 
10 loops, best of 3: 178 ms per loop 

#jezrael3 
In [219]: %timeit f(df) 
100 loops, best of 3: 3.63 ms per loop 

चेतावनी

परिणाम प्रदर्शन का पता नहीं समूहों की संख्या है, जो समय इन समाधानों में से कुछ के लिए एक बहुत प्रभावित करेगा दिया।

6

दो संभावनाओं, groupby + nth + map या replace

df['b_new'] = df.a.map(df.groupby('a').b.nth(-1)) 

या, साथ

df['b_new'] = df.a.replace(df.groupby('a').b.nth(-1)) 

तुम भी nth(-1)last() से बदल सकते हैं (वास्तव में, ऐसा करने से यह एक छोटे से बनाने के लिए होता है तेज़), लेकिन nth आपको b में प्रत्येक समूह से किस आइटम को चुनने के लिए अधिक लचीलापन देता है।


df 

    a b b_new 
0 1 20  21 
1 1 21  21 
2 2 30  30 
3 3 40  41 
4 3 41  41 
2

मुझे लगता है कि यह तेजी से होना चाहिए

df.merge(df.drop_duplicates('a',keep='last'),on='a',how='left') 
Out[797]: 
    a b_x b_y 
0 1 20 21 
1 1 21 21 
2 2 30 30 
3 3 40 41 
4 3 41 41 
संबंधित मुद्दे