2016-04-06 2 views
5

मेरे पास एक डेटाफ्रेम है जिसे आईडी द्वारा समूहीकृत किया गया है। कई समूह हैं, और प्रत्येक समूह में पंक्तियों की एक चर संख्या है। सभी समूहों की पहली तीन पंक्तियों में दिलचस्प डेटा नहीं है। मैं निम्नलिखित समूह में एक पंक्ति बनाने के लिए प्रत्येक समूह में पहली तीन पंक्तियों को "पतन" करना चाहता हूं:पांडा: समेकन द्वारा प्रत्येक समूह में पहली पंक्तियों को संकुचित करें

'आईडी', और 'टाइप' नई 'ध्वस्त' पंक्ति में समान रहेगा।
'grp_idx' में बदल दिया जाएगा "0" जब पहली तीन पंक्तियों का एकत्रीकरण होता
col_1 प्रथम तीन पंक्तियां का योग होगा
col_2 प्रथम तीन पंक्तियां
'ध्वज' का योग होगा "ध्वस्त" पंक्ति में 0 होगा यदि मूल्य पहले 3 पंक्तियों में सभी 0 हैं। 'ध्वज' 1 होगा यदि यह पहली तीन पंक्तियों में से किसी एक में है। (एक सरल योग इस तर्क के लिए पर्याप्त होगा, के बाद से झंडा केवल सभी समूहों के लिए एक पंक्ति में सेट किया गया है)

यहाँ dataframe कैसा दिखाई देता है की एक उदाहरण है:

import pandas as pd 
import numpy as np 
df = pd.DataFrame.from_items([ 
    ('id', [283,283,283,283,283,283,283,756,756,756]), 
    ('type', ['A','A','A','A','A','A','A','X','X','X']), 
    ('grp_idx', [1,2,3,4,5,6,7,1,2,3]), 
    ('col_1', [2,4,6,8,10,12,14,5,10,15]), 
    ('col_2', [3,6,9,12,15,18,21,1,2,3]), 
    ('flag', [0,0,0,0,0,0,1,0,0,1]), 
    ]); 
print(df) 

    id type grp_idx col_1 col_2 flag 
0 283 A  1  2  3  0 
1 283 A  2  4  6  0 
2 283 A  3  6  9  0 
3 283 A  4  8  12  0 
4 283 A  5  10  15  0 
5 283 A  6  12  18  0 
6 283 A  7  14  21  1 
7 756 X  1  5  1  0 
8 756 X  2  10  2  0 
9 756 X  3  15  3  1 

प्रसंस्करण के बाद, मैं उम्मीद dataframe देखने के लिए की तरह:

ID Type grp_idx col_1 col_2 flag 
283 A   0  12  18  0 
283 A   4  8  12  0 
283 A   5  10  15  0 
283 A   6  12  18  0 
283 A   7  14  21  1 
756 X   0  30  6  1 

मुझे यकीन है कि आगे बढ़ने के लिए कैसे नहीं हूँ। मैं के साथ

df.groupby ('आईडी') के चारों ओर खेलने के लिए कोशिश कर रहा था। सिर (3) .sum()

लेकिन यह नहीं कर रहा है कि मैं क्या जरूरत है। किसी भी मदद, सुझाव, कोड स्निपेट वास्तव में सराहना की जाएगी।

उत्तर

2

आप grp_idx की स्थापना द्वारा शुरू कर सकते हैं:

df["grp_idx"] = np.where(df.groupby("id").cumcount()<3, 0, df["grp_idx"]) 

id और grp_idx अब बनाते हैं तो आप समूहीकरण हैं:

df.groupby(["id", "type", "grp_idx"]).sum().reset_index() 

    id type grp_idx col_1 col_2 flag 
0 283 A  0  12  18  0 
1 283 A  4  8  12  0 
2 283 A  5  10  15  0 
3 283 A  6  12  18  0 
4 283 A  7  14  21  1 
5 756 X  0  30  6  1 

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

+0

बहुत बढ़िया !! मैं इसे अपने आप कभी नहीं समझता। मदद करने के लिए समय निकालने के लिए धन्यवाद। – Learner

+0

आपका स्वागत है। यह एक अच्छा अभ्यास था। – ayhan

2

मैं आप जिस तरह से आप चाहते हैं में गठबंधन करने के लिए में aggregate() करने की आवश्यकता है के बाद आप groupby() फोन

df.groupby('id').head(3).sum() 

के साथ चारों ओर खेलने के लिए कोशिश कर रहा था,। कुछ इस तरह का प्रयास करें:

# function to sum the first 3 rows 
def head_sum(x): 
    return x.head(3).sum() 

# function to get max of first 3 rows 
def head_max(x): 
    return x.head(3).max() 

# We can use a dictionary in `aggregate()` to call a 
# specific function for each column in the groupby 
column_funcs = {'col_1': head_sum, 
       'col_2': head_sum, 
       'flag': head_max, 
       'id': max, # all the vals should be the same 
       'type': max} # are the 'id' and 'type' always matched? 
collapsed = df.groupby('id').aggregate(column_funcs) 
collapsed['grp_idx'] = 0 

new_df = pd.concat([df, collapsed]) 

विभाजन लागू-गठबंधन दृष्टिकोण पर एक बहुत अधिक जानकारी के लिए here देखें।

+0

धन्यवाद जॅचरी! आपके द्वारा उल्लिखित तकनीक वास्तव में अच्छी है। कुछ मैं अपने कम ज्ञान में जोड़ दूंगा। आपका सुझाव निश्चित रूप से आवश्यकतानुसार पूरा करने के लिए काम कर सकता है। मुझे बस पहली तीन पंक्तियां छोड़नी पड़ेगी। अपना ज्ञान साझा करने के लिए फिर से धन्यवाद। – Learner

संबंधित मुद्दे