पंडों की कुल गणना अलग है


94

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

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

मैं जो करना चाहता हूं, वह एक ही समय में अवधि और गिनती भिन्न है, लेकिन मैं count_ististist के लिए एक समान नहीं मिल सकता है:

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

मुझे लगता है कि मुझे केवल एक फ़ंक्शन प्रदान करने की आवश्यकता है जो श्रृंखला फ़ंक्शन के अलग-अलग आइटमों की संख्या को कुल फ़ंक्शन पर लौटाता है, लेकिन मेरे पास अपने निपटान में विभिन्न पुस्तकालयों के लिए बहुत अधिक जोखिम नहीं है। इसके अलावा, ऐसा लगता है कि ग्रुपबी ऑब्जेक्ट पहले से ही इस जानकारी को जानता है, इसलिए क्या मैं सिर्फ प्रयास को दोहरा नहीं सकता हूं?

जवाबों:


154

कैसे के बारे में:

>>> 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 वह है जो मुझे नहीं मिल सका, ठीक है, सही तरीके से काम नहीं कर सका। अड़चन में बहुत स्पष्ट है। धन्यवाद!
डेव

5
यह उत्तर पुराना है। अब आप nuniqueसीधे उपयोग कर सकते हैं । नीचे @Blodwyn सुअर का समाधान देखें
टेड

धन्यवाद @TedPetrou, मैं कोडर पूर्व में ब्लोडविन सुअर के रूप में जाना जाता है;)
रिकी मैकमास्टर

अरे क्या आप जानते हैं कि नॉन-डुप्लिकेट गिनती कैसे प्राप्त करें?
Ambleu

61

an nunique ’पांडा के लिए एक विकल्प है () 0.20.0 पांडा के बाद से, इसलिए:

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

क्या यह संभव है कि एग और अद्वितीय मूल्य प्राप्त करें? कुछ इस तरहduration: np.unique
आदमी

@ गुगी कोशिशdf.groupby('date').agg({'user_id': lambda s: s.unique().reset_index(drop=True)})
बॉलपॉइंटबैन

हम आउटपुट कैसे प्राप्त करते हैं?

17

बस पहले से दिए गए उत्तरों को जोड़ते हुए, स्ट्रिंग का उपयोग करने वाला समाधान "nunique"बहुत तेज़ लगता है, यहाँ पर परीक्षण किया गया ~ 21M पंक्तियों के डेटाफ़्रेम, फिर ~ 2M पर समूहीकृत

%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
अच्छा पकड़ा! मुझे लगता है कि यह "लैम्ब्डा" / "अन्य फ़ंक्शन" मामले में बी / सी है, यह क्रमिक रूप से लागू किया जाता है, जबकि "ज्ञात" फ़ंक्शन पूरे कॉलम में एक वेक्टर फैशन में लागू होते हैं।
उफोस

जो समाधान @Blodwyn सुअर से है?
चोगग

@ चोगे, सबसे तेज!
m-dz

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