पंडों के ग्रुपबी ()। सम () के आउटपुट से मैं एक नया कॉलम कैसे बनाऊं?


84

groupbyगणना से एक नया कॉलम बनाने की कोशिश की जा रही है । नीचे दिए गए कोड में, मुझे प्रत्येक तिथि के लिए सही गणना किए गए मान मिलते हैं (नीचे समूह देखें) लेकिन जब मैं df['Data4']इसके साथ एक नया कॉलम ( ) बनाने की कोशिश करता हूं तो मुझे NaN मिलता है। इसलिए मैं Data3सभी तिथियों के योग के साथ डेटाफ्रेम में एक नया कॉलम बनाने की कोशिश कर रहा हूं और प्रत्येक तिथि पंक्ति पर लागू होता हूं । उदाहरण के लिए, 2015-05-08 2 पंक्तियों में है (कुल 50 + 5 = 55) और इस नए कॉलम में मैं दोनों पंक्तियों में 55 रखना चाहूंगा।

import pandas as pd
import numpy as np
from pandas import DataFrame

df = pd.DataFrame({
    'Date' : ['2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05', '2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05'], 
    'Sym'  : ['aapl', 'aapl', 'aapl', 'aapl', 'aaww', 'aaww', 'aaww', 'aaww'], 
    'Data2': [11, 8, 10, 15, 110, 60, 100, 40],
    'Data3': [5, 8, 6, 1, 50, 100, 60, 120]
})

group = df['Data3'].groupby(df['Date']).sum()

df['Data4'] = group

जवाबों:


192

आप इसका उपयोग करना चाहते transformहैं, एक श्रृंखला को df के साथ संरेखित करेंगे ताकि आप फिर इसे एक नए कॉलम के रूप में जोड़ सकें:

In [74]:

df = pd.DataFrame({'Date': ['2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05', '2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05'], 'Sym': ['aapl', 'aapl', 'aapl', 'aapl', 'aaww', 'aaww', 'aaww', 'aaww'], 'Data2': [11, 8, 10, 15, 110, 60, 100, 40],'Data3': [5, 8, 6, 1, 50, 100, 60, 120]})
​
df['Data4'] = df['Data3'].groupby(df['Date']).transform('sum')
df
Out[74]:
   Data2  Data3        Date   Sym  Data4
0     11      5  2015-05-08  aapl     55
1      8      8  2015-05-07  aapl    108
2     10      6  2015-05-06  aapl     66
3     15      1  2015-05-05  aapl    121
4    110     50  2015-05-08  aaww     55
5     60    100  2015-05-07  aaww    108
6    100     60  2015-05-06  aaww     66
7     40    120  2015-05-05  aaww    121

अगर हमारे पास दूसरा समूह है जैसे कि यहाँ क्या होता है: stackoverflow.com/a/40067099/281545
Mr_and_Mrs_D

@Mr_and_Mrs_D आपको उस कॉलम को वापस जोड़ने के लिए इंडेक्स को रीसेट करना होगा और उस स्थिति में कॉमन कॉलम पर लेफ्ट मर्ज करना होगा
EdChum

10
वैकल्पिक रूप से, एक का उपयोग कर सकते हैं df.groupby('Date')['Data3'].transform('sum')(जो मुझे याद रखना थोड़ा आसान लगता है)।
क्लेब

42

मैं ग्रुपबी () के साथ एक नया कॉलम कैसे बनाऊँ?

इसके दो तरीके हैं - एक सीधा और दूसरा थोड़ा और दिलचस्प।


सबका पसंदीदा: GroupBy.transform()साथ'sum'

@ ईडी चुम का जवाब थोड़ा सरल किया जा सकता है। के DataFrame.groupbyबजाय बुलाओ Series.groupby। यह सरल वाक्य रचना में परिणाम करता है।

# The setup.
df[['Date', 'Data3']]

         Date  Data3
0  2015-05-08      5
1  2015-05-07      8
2  2015-05-06      6
3  2015-05-05      1
4  2015-05-08     50
5  2015-05-07    100
6  2015-05-06     60
7  2015-05-05    120

df.groupby('Date')['Data3'].transform('sum')

0     55
1    108
2     66
3    121
4     55
5    108
6     66
7    121
Name: Data3, dtype: int64 

यह तेज है,

df2 = pd.concat([df] * 12345)

%timeit df2['Data3'].groupby(df['Date']).transform('sum')
%timeit df2.groupby('Date')['Data3'].transform('sum')

10.4 ms ± 367 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
8.58 ms ± 559 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

अपरंपरागत, लेकिन अपने विचार पर ध्यान दें: GroupBy.sum()+Series.map()

मैं एपीआई में एक दिलचस्प idiosyncrasy पर ठोकर खाई। जो मैं बताता हूं, आप इसे 0.20 से अधिक किसी भी बड़े संस्करण पर पुन: पेश कर सकते हैं (मैंने इसे 0.23 और 0.24 पर परीक्षण किया है)। ऐसा लगता है जैसे आप लगातार समय के कुछ मिलीसेकेंड को दाढ़ी बना सकते हैं transformयदि आप इसके बजाय एक सीधा फ़ंक्शन का GroupByउपयोग करते हैं और इसे प्रसारित करते हैं map:

df.Date.map(df.groupby('Date')['Data3'].sum())

0     55
1    108
2     66
3    121
4     55
5    108
6     66
7    121
Name: Date, dtype: int64

तुलना करना

df.groupby('Date')['Data3'].transform('sum')

0     55
1    108
2     66
3    121
4     55
5    108
6     66
7    121
Name: Data3, dtype: int64

मेरे परीक्षणों से पता चलता है कि mapएक सा तेजी से होता है यदि आप सीधे उपयोग करने के लिए खर्च कर सकते हैं, तो GroupByसमारोह (जैसे mean, min, max, first, आदि)। यह लगभग ~ 200 हजार रिकॉर्ड तक की अधिकांश सामान्य स्थितियों के लिए कम या ज्यादा तेज है। उसके बाद, प्रदर्शन वास्तव में डेटा पर निर्भर करता है।

(बाएं: v0.23, दाएं: v0.24)

पता करने के लिए अच्छा विकल्प है, और बेहतर है अगर आपके पास छोटी संख्या में समूह हैं। । । लेकिन मैं transformपहली पसंद के रूप में सलाह दूंगा। सोचा कि यह वैसे भी साझा करने लायक था।

संदर्भ के लिए बेंचमार्किंग कोड:

import perfplot

perfplot.show(
    setup=lambda n: pd.DataFrame({'A': np.random.choice(n//10, n), 'B': np.ones(n)}),
    kernels=[
        lambda df: df.groupby('A')['B'].transform('sum'),
        lambda df:  df.A.map(df.groupby('A')['B'].sum()),
    ],
    labels=['GroupBy.transform', 'GroupBy.sum + map'],
    n_range=[2**k for k in range(5, 20)],
    xlabel='N',
    logy=True,
    logx=True
)

1
यह जानकर अच्छा लगता है! क्या आप भविष्य के कम से कम संस्करण क्रमांक में (सहित भविष्य में) मन चाहेंगे? प्रदर्शन अंतर दिलचस्प है, लेकिन ये सब, कार्यान्वयन विवरण, जो भविष्य में इस्त्री किए जा सकते हैं। खासतौर पर अगर डेवलपर्स आपकी पोस्ट पर ध्यान दें।
जप

@ जेपी यूप फेयर! वर्जन जोड़े हैं। यह 0.23 पर परीक्षण किया गया था, लेकिन मेरा मानना ​​है कि अंतर तब तक देखा जाता है जब तक आपके पास 0.20 से अधिक कोई भी संस्करण न हो।
CS95
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.