2013-09-01 9 views
48

मान लें कि मेरे पास उपयोगकर्ता गतिविधि का लॉग है और मैं प्रति दिन अद्वितीय उपयोगकर्ताओं की संख्या और अद्वितीय उपयोगकर्ताओं की संख्या उत्पन्न करना चाहता हूं।पांडा कुल गणना अलग

import numpy as np 
import pandas as pd 
df = pd.DataFrame({'date': ['2013-04-01','2013-04-01','2013-04-01','2013-04-02', '2013-04-02'], 
    'user_id': ['0001', '0001', '0002', '0002', '0002'], 
    'duration': [30, 15, 20, 15, 30]}) 

अवधि को समेकित करना बिल्कुल स्पष्ट है:

group = df.groupby('date') 
agg = group.aggregate({'duration': np.sum}) 
agg 
      duration 
date 
2013-04-01  65 
2013-04-02  45 

योग अवधि मुझे क्या करना चाहते हैं और एक ही समय में distincts गिनती, लेकिन मैं के लिए एक समान लगता है नहीं कर पा रहे count_distinct:

agg = group.aggregate({ 'duration': np.sum, 'user_id': count_distinct}) 

यह काम करता है, लेकिन निश्चित रूप से एक बेहतर तरीका है, नहीं?

group = df.groupby('date') 
agg = group.aggregate({'duration': np.sum}) 
agg['uv'] = df.groupby('date').user_id.nunique() 
agg 
      duration uv 
date 
2013-04-01  65 2 
2013-04-02  45 1 

मैं सोच रहा हूँ मैं सिर्फ एक समारोह है कि एकीकृत फ़ंक्शन करने के लिए एक श्रृंखला वस्तु की विशिष्ट वस्तुओं की गणना देता है प्रदान करने की आवश्यकता है, लेकिन मैं पर विभिन्न पुस्तकालयों के लिए जोखिम का एक बहुत जरूरत नहीं है मेरी निपटान। साथ ही, ऐसा लगता है कि ग्रुपबी ऑब्जेक्ट पहले ही इस जानकारी को जानता है, तो क्या मैं सिर्फ प्रयास को डुप्लिकेट नहीं करूँगा?

उत्तर

86

कैसे या तो के बारे में:

>>> df 
     date duration user_id 
0 2013-04-01  30 0001 
1 2013-04-01  15 0001 
2 2013-04-01  20 0002 
3 2013-04-02  15 0002 
4 2013-04-02  30 0002 
>>> df.groupby("date").agg({"duration": np.sum, "user_id": pd.Series.nunique}) 
      duration user_id 
date       
2013-04-01  65  2 
2013-04-02  45  1 
>>> df.groupby("date").agg({"duration": np.sum, "user_id": lambda x: x.nunique()}) 
      duration user_id 
date       
2013-04-01  65  2 
2013-04-02  45  1 
+1

यह है कि करने के लिए वर्गीकृत किया। pd.Series.nunique वह है जो मुझे नहीं मिला, ठीक है, सही तरीके से काम नहीं कर सका। हिंडसाइट में बहुत स्पष्ट है। धन्यवाद! – dave

+1

यह उत्तर पुराना है। अब आप सीधे 'नूनिक' का उपयोग कर सकते हैं। –

13

'nunique' अब .agg() के लिए एक विकल्प है, तो यह है:

df.groupby('date').agg({'duration': 'sum', 'user_id': 'nunique'}) 
+0

से नीचे @ ब्लाडविन पिग का समाधान देखें क्या यह अद्वितीय मूल्यों को प्राप्त करना और प्राप्त करना संभव है? कुछ अवधि की तरह: np.unique' – guy

3

बस जवाब पहले ही दिया को जोड़ने, @Blodwyn सुअर समाधान सबसे कुशल है।

यह समाधान बहुत तेजी से लगता है, यहाँ ~ पर 21M पंक्तियों dataframe परीक्षण किया है, तो ~ 2 एम

%time _=g.agg({"id": lambda x: x.nunique()}) 
CPU times: user 3min 3s, sys: 2.94 s, total: 3min 6s 
Wall time: 3min 20s 

%time _=g.agg({"id": pd.Series.nunique}) 
CPU times: user 3min 2s, sys: 2.44 s, total: 3min 4s 
Wall time: 3min 18s 

%time _=g.agg({"id": 'nunique'}) 
CPU times: user 14 s, sys: 4.76 s, total: 18.8 s 
Wall time: 24.4 s 
+1

अच्छा पकड़ो! मुझे लगता है कि यह "लैम्ब्डा"/"अन्य फ़ंक्शन" मामले में बी/सी है, यह अनुक्रमिक रूप से लागू होता है, जबकि "ज्ञात" फ़ंक्शंस वेक्टरकृत फैशन में पूरे कॉलम पर लागू होते हैं। – Ufos

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