2013-06-21 11 views
5

में प्रत्येक समूह के लिए प्रत्येक पंक्ति का आकलन करें पांडा में, मैं एक नया स्तंभ कैसे जोड़ सकता हूं जो किसी दिए गए समूह के आधार पर पंक्तियों को दर्शाता है?डेटाफ्रेम

import pandas as pd 
import numpy as np 

a_list = ['A', 'B', 'C', 'A', 'A', 'C', 'B', 'B', 'A', 'C'] 
df = pd.DataFrame({'col_a': a_list, 'col_b': range(10)}) 
df 
    col_a col_b 
0  A  0 
1  B  1 
2  C  2 
3  A  3 
4  A  4 
5  C  5 
6  B  6 
7  B  7 
8  A  8 
9  C  9 

मैं एक col_c है कि मुझे "समूह" col_a का एक समूह और col_b की छंटाई के आधार पर की वां पंक्ति देता जोड़ना चाहते हैं:

उदाहरण के लिए निम्नलिखित DataFrame मान।

वांछित उत्पादन:

col_a col_b col_c 
0  A  0  1 
3  A  3  2 
4  A  4  3 
8  A  8  4 
1  B  1  1 
6  B  6  2 
7  B  7  3 
2  C  2  1 
5  C  5  2 
9  C  9  3 

मैं col_c को पाने के लिए संघर्ष कर रहा हूँ। आप उचित समूहिंग और .sort_index(by=['col_a', 'col_b']) के साथ सॉर्टिंग कर सकते हैं, अब यह उस नए कॉलम को प्राप्त करने और प्रत्येक पंक्ति को लेबल करने का विषय है।

उत्तर

12

वहाँ, cumcount है ठीक इस मामले के लिए:

df['col_c'] = g.cumcount() 

यह डॉक्स में कहते हैं:

संख्या है कि समूह की लंबाई के 0 से प्रत्येक समूह में प्रत्येक आइटम - 1.


मूल जवाब (से पहले cumcount परिभाषित किया गया था)।

def add_col_c(x): 
    x['col_c'] = np.arange(len(x)) 
    return x 

स्तंभ col_a पहले इसके द्वारा सॉर्ट:

आप यह करने के लिए एक सहायक समारोह बना सकते हैं

In [12]: g = df.groupby('col_a', as_index=False) 

In [13]: g.apply(add_col_c) 
Out[13]: 
    col_a col_b col_c 
3  A  3  0 
8  A  8  1 
0  A  0  2 
4  A  4  3 
6  B  6  0 
1  B  1  1 
7  B  7  2 
9  C  9  0 
2  C  2  1 
5  C  5  2 

:

In [11]: df.sort('col_a', inplace=True) 

फिर प्रत्येक समूह भर में इस समारोह लागू 1,2,... प्राप्त करने के लिए आप को couls से np.arange(1, len(x) + 1)

+0

यह मूल रूप से प्रश्न का उत्तर देता है - हालांकि gjreda ने col_b द्वारा क्रमबद्ध col_a को गिनने के लिए कहा। – gabe

+0

@gabe यह अजीब है, यह सुनिश्चित नहीं है कि मैंने इसे कैसे प्रबंधित किया:) \ –

+0

बहुत बढ़िया, धन्यवाद @ एंडीहेडन। पता था कि यह एक समूह बनने जा रहा था, लेकिन यह पता नहीं लगा कि इसे ठीक से कैसे लागू किया जाए। –

1

आपको लगता है कि से निपटने के लिए अपने स्वयं के समारोह को परिभाषित कर सकते हैं:

In [58]: def func(x): 
    ....:  x['col_c'] = x['col_a'].argsort() + 1 
    ....:  return x 
    ....: 

In [59]: df.groupby('col_a').apply(func) 
Out[59]: 
    col_a col_b col_c 
0  A  0  1 
3  A  3  2 
4  A  4  3 
8  A  8  4 
1  B  1  1 
6  B  6  2 
7  B  7  3 
2  C  2  1 
5  C  5  2 
9  C  9  3 
2

दिए गए उत्तर दोनों प्रत्येक समूह के लिए एक अजगर समारोह बुला शामिल है, और एक vectorized दृष्टिकोण तेजी से (मैं होना चाहिए, अगर आप कई समूह हैं चेक किया गया है)।

In [5]: df.sort(['col_a', 'col_b'], inplace=True, ascending=(False, False)) 
In [6]: sizes = df.groupby('col_a', sort=False).size().values 
In [7]: df['col_c'] = np.arange(sizes.sum()) - np.repeat(sizes.cumsum() - sizes, sizes) 
In [8]: print df 
    col_a col_b col_c 
9  C  9  0 
5  C  5  1 
2  C  2  2 
7  B  7  0 
6  B  6  1 
1  B  1  2 
8  A  8  0 
4  A  4  1 
3  A  3  2 
0  A  0  3 
+0

मेरे लिए तेज़ी से रास्ता। बहुत बहुत धन्यवाद। – DanT

0

आप समारोह को बदलने का प्रयोग कर सकते cumcount पर इस का उपयोग करने पर 1.

#Create a column of ones 
df['col_c'] = 1 
#Add them sequentially within the group and apply that column to the dataset. 
df['col_c'] = df.groupby('col_a')['col_c'].transform('cumsum') 

केवल संभावित लाभ गणना शुरू करने के लिए() है:

यहाँ मेरी शुद्ध numpy सुझाव है कि पांडा डेटाफ्रेम ऑब्जेक्ट्स के भीतर गणना 0 के बजाय 1 पर शुरू होती है।यद्यपि यह एक लाभ का आह्वान करने के लिए बहुत दूर है: डी