पंडों GroupBy.agg () का उपयोग करके एक ही कॉलम के कई एकत्रीकरण


127

क्या कॉल करने के लिए बिना f1, f2एक ही कॉलम में दो अलग-अलग एग्रीगेटिंग फ़ंक्शंस लागू करने के लिए एक पांडा निर्मित हैdf["returns"]agg() कई बार ?

उदाहरण डेटाफ़्रेम:

import pandas as pd
import datetime as dt

pd.np.random.seed(0)
df = pd.DataFrame({
         "date"    :  [dt.date(2012, x, 1) for x in range(1, 11)], 
         "returns" :  0.05 * np.random.randn(10), 
         "dummy"   :  np.repeat(1, 10)
}) 

कृत्रिम रूप से गलत, लेकिन सहज रूप से सही, इसे करने का तरीका होगा:

# Assume `f1` and `f2` are defined for aggregating.
df.groupby("dummy").agg({"returns": f1, "returns": f2})

जाहिर है, पायथन डुप्लिकेट कुंजियों की अनुमति नहीं देता है। क्या इनपुट को व्यक्त करने का कोई अन्य तरीका है agg()? शायद एक [(column, function)]ही स्तंभ पर लागू कई कार्यों को अनुमति देने के लिए टुपल्स की एक सूची बेहतर काम करेगी? परंतुagg() ऐसा लगता है कि यह केवल एक शब्दकोश को स्वीकार करता है।

क्या एक सहायक फ़ंक्शन को परिभाषित करने के अलावा इसके लिए एक वर्कअराउंड है जो इसके अंदर दोनों फ़ंक्शन को लागू करता है? (यह एकत्रीकरण के साथ कैसे काम करेगा?)



2
0.25 से, पांडा कई एकत्रीकरण के साथ-साथ आउटपुट कॉलम का नाम बदलने के लिए अधिक सहज वाक्यविन्यास प्रदान करता है। नामांकित एकत्रीकरण पर प्रलेखन देखें ।
cs95

FYI करें इस सवाल पर वापस जाने के लिए रास्ता था pandas 0.8.x 9/2012
smci

1
FYI करें स्वीकार किए गए उत्तर को भी हटा दिया गया है - agg () dicts का एक ताना-बाना नहीं।
cs95

@ सीएस 95: मुझे पता है कि यह पदावनत है, मैं कह रहा हूं कि एसओ पुराने संस्करणों से पुराने बासी समाधान से अटे पड़े हैं। SO के पास ऐसा कोई तरीका नहीं है जो टिप्पणियों के अलावा - को भी चिह्नित कर सके।
एसएमसीआई

जवाबों:


159

आप बस एक सूची के रूप में कार्य कर सकते हैं:

In [20]: df.groupby("dummy").agg({"returns": [np.mean, np.sum]})
Out[20]:         
           mean       sum
dummy                    
1      0.036901  0.369012

या एक शब्दकोष के रूप में:

In [21]: df.groupby('dummy').agg({'returns':
                                  {'Mean': np.mean, 'Sum': np.sum}})
Out[21]: 
        returns          
           Mean       Sum
dummy                    
1      0.036901  0.369012

4
क्या परिणाम कॉलम के नाम निर्दिष्ट करने का कोई तरीका है?
बेन

3
@ मुझे लगता है कि आपको बाद में नाम बदलना होगा। टॉम ऑग्सपर्गर द्वारा उदाहरण (सेल 25 देखें)
स्टीवेबाका

1
@ जेन: मैंने एक उदाहरण जोड़ा
bmu

10
@ sparc_spread एक सूची के रूप में कई कार्यों को पारित करना अच्छी तरह से पांडा प्रलेखन में वर्णित है । एक शब्दकोश के रूप में कई कार्यों का नाम बदलना और पारित करना भविष्य के पांडा के संस्करण में चित्रित किया जाएगा। विवरण 0.20 परिवर्तन लॉग में हैं , जिसे मैंने एसओ पर कहीं और संक्षेप में प्रस्तुत किया है
joelostblom

3
यह पहले ही कहा जा चुका है, लेकिन आउटपुट कॉलम का नाम बदलने के लिए शब्दकोशों का उपयोग उम्र से हटा दिया जाता है। इसके बजाय आप tuples की सूची निर्दिष्ट कर सकते हैं। इस जवाब को देखें।
सीएस 95

101

TLDR; पंडों के groupby.aggपास एक कॉलम पर (1) एकत्रीकरणों को निर्दिष्ट करने के लिए एक नया और आसान सिंटैक्स है, और (2) एक कॉलम पर कई एकत्रीकरण हैं। तो, पंडों के लिए ऐसा करने के लिए = = 0.25 , उपयोग करें

df.groupby('dummy').agg(Mean=('returns', 'mean'), Sum=('returns', 'sum'))

           Mean       Sum
dummy                    
1      0.036901  0.369012

या

df.groupby('dummy')['returns'].agg(Mean='mean', Sum='sum')

           Mean       Sum
dummy                    
1      0.036901  0.369012

पंडों> = 0.25: नामित एकत्रीकरण

पंडों ने GroupBy.aggनामकरण एकत्रीकरण को निर्दिष्ट करने के लिए एक अधिक सहज वाक्यविन्यास के पक्ष में व्यवहार को बदल दिया है । देखें संवर्द्धन पर 0.25 डॉक्स अनुभाग के साथ ही प्रासंगिक GitHub मुद्दों GH18366 और GH26512

प्रलेखन से,

आउटपुट कॉलम नामों पर नियंत्रण के साथ कॉलम-विशिष्ट एकत्रीकरण का समर्थन करने के लिए, पांडा विशेष सिंटैक्स को स्वीकार करता है GroupBy.agg(), जिसे "एग्रीगेशन" नाम से जाना जाता है, जहां

  • कीवर्ड आउटपुट कॉलम नाम हैं
  • मान tuples हैं जिसका पहला तत्व चयन करने के लिए कॉलम है और दूसरा तत्व उस कॉलम पर लागू करने के लिए एकत्रीकरण है। पंडों ने पंडों को प्रदान किया। नामांकित प्रत्येक खेत के नाम के साथ ['कॉलम', 'एग्गफंक'] यह स्पष्ट करने के लिए कि तर्क क्या हैं। हमेशा की तरह, एकत्रीकरण एक कॉल करने योग्य या एक स्ट्रिंग उपनाम हो सकता है।

अब आप कीवर्ड तर्कों के माध्यम से एक टपल पास कर सकते हैं। टुपल्स के प्रारूप का अनुसरण करते हैं (<colName>, <aggFunc>)

import pandas as pd

pd.__version__                                                                                                                            
# '0.25.0.dev0+840.g989f912ee'

# Setup
df = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
                   'height': [9.1, 6.0, 9.5, 34.0],
                   'weight': [7.9, 7.5, 9.9, 198.0]
})

df.groupby('kind').agg(
    max_height=('height', 'max'), min_weight=('weight', 'min'),)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5

वैकल्पिक रूप से, आप उपयोग कर सकते हैं pd.NamedAgg(अनिवार्य रूप से एक नामांकित) जो चीजों को अधिक स्पष्ट बनाता है।

df.groupby('kind').agg(
    max_height=pd.NamedAgg(column='height', aggfunc='max'), 
    min_weight=pd.NamedAgg(column='weight', aggfunc='min')
)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5

यह श्रृंखला के लिए और भी सरल है, बस एक कीवर्ड तर्क के लिए aggfunc पास करें।

df.groupby('kind')['height'].agg(max_height='max', min_height='min')    

      max_height  min_height
kind                        
cat          9.5         9.1
dog         34.0         6.0       

अंत में, यदि आपके कॉलम के नाम मान्य अजगर पहचानकर्ता नहीं हैं, तो अनपैकिंग वाले शब्दकोश का उपयोग करें:

df.groupby('kind')['height'].agg(**{'max height': 'max', ...})

पंडों <0.25

0.24 तक के पंडों के अधिक हालिया संस्करणों में, अगर एकत्रीकरण आउटपुट के लिए स्तंभ नामों को निर्दिष्ट करने के लिए एक शब्दकोश का उपयोग किया जाता है, तो आपको एक मिलेगा FutureWarning:

df.groupby('dummy').agg({'returns': {'Mean': 'mean', 'Sum': 'sum'}})
# FutureWarning: using a dict with renaming is deprecated and will be removed 
# in a future version

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

df.groupby("dummy").agg({'returns': [('op1', 'sum'), ('op2', 'mean')]})

        returns          
            op1       op2
dummy                    
1      0.328953  0.032895

या,

df.groupby("dummy")['returns'].agg([('op1', 'sum'), ('op2', 'mean')])

            op1       op2
dummy                    
1      0.328953  0.032895

4
इंटरफ़ेस के नए संस्करण का उपयोग करके अधिक स्पष्ट और स्वच्छ समाधान का उपयोग करने के कारण यह शीर्ष उत्तर होना चाहिए।
NKSHELL

नाम एकत्रीकरण के लिए उपयोग किए जाने वाले उदाहरण एक ही स्तंभ पर कई एकत्रीकरण का उपयोग करने की मूल समस्या को हल नहीं करते हैं। उदाहरण के लिए, क्या आप न्यूनतम और अधिकतम ऊंचाई दोनों के लिए पहले उप-क्रमांकन के बिना समग्र कर सकते हैं df.groupby('kind')['height']?
विजेता

1
@victor मैंने जवाब के शीर्ष पर एक TLDR जोड़ा जो सीधे प्रश्न को संबोधित करता है। और आपके दूसरे प्रश्न का उत्तर हां है, कृपया मेरे उत्तर पर संपादित पर एक नज़र डालें।
cs95

इस तरह के कई स्तंभों को एकत्रित करने के लिए आपके> = 0.25 उत्तर के अंतिम उदाहरण के लिए एक अधिक सामान्य कोड बहुत अच्छा रहा होगा। df.groupby("kind").agg(**{ 'max height': pd.NamedAgg(column='height', aggfunc=max), 'min weight': pd.NamedAgg(column='weight', aggfunc=min) })
ओनूर एसे

6

क्या यह काम पसंद आएगा:

In [7]: df.groupby('dummy').returns.agg({'func1' : lambda x: x.sum(), 'func2' : lambda x: x.prod()})
Out[7]: 
              func2     func1
dummy                        
1     -4.263768e-16 -0.188565

2
नहीं, यह काम नहीं करता है। यदि आप aggregateइसके लिए डॉक स्ट्रिंग को देखते हैं, तो स्पष्ट रूप से कहते हैं कि जब कोई dictपास हो जाता है, तो चाबियाँ कॉलम नाम होनी चाहिए। तो या तो आपका उदाहरण कुछ ऐसा है जिसे आपने इस त्रुटि की जाँच के बिना टाइप किया है, या फिर पंडों ने अपने स्वयं के डॉक्स यहाँ तोड़ दिए।
ely

N / MI ने returnsवहां अतिरिक्त कॉल नहीं देखा । तो यह कुल का श्रृंखला संस्करण है? मैं कुल के DataFrame संस्करण को करना चाह रहा हूं, और मैं एक ही बार में प्रत्येक स्तंभ पर कई अलग-अलग एकत्रीकरण लागू करना चाहता हूं।
Ely

1
इसे आज़माएँ: df.groupby ('dummy')। agg ({'रिटर्न': {'func1': lambda x: x.sum (), 'func2': lambda x: x.mean ()})
चांग वह

यह बिना किसी संदेश के एक जोरदार त्रुटि देता है। कोड (pandas.core.internals.py, लाइनों 406-408, संस्करण 0.7.3) के लुक से ऐसा लगता है कि यह अंत में एक चेक करता है, यह सुनिश्चित करने के लिए कि इसमें पहले से अधिक कुंजियाँ नहीं हैं। एकत्रीकरण शब्दकोश की परत।
ely

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