पांडा डेटाफ्रेम ग्रुपबी डेटाइम महीने


90

एक सीएसवी फ़ाइल पर विचार करें:

string,date,number
a string,2/5/11 9:16am,1.0
a string,3/5/11 10:44pm,2.0
a string,4/22/11 12:07pm,3.0
a string,4/22/11 12:10pm,4.0
a string,4/29/11 11:59am,1.0
a string,5/2/11 1:41pm,2.0
a string,5/2/11 2:02pm,3.0
a string,5/2/11 2:56pm,4.0
a string,5/2/11 3:00pm,5.0
a string,5/2/14 3:02pm,6.0
a string,5/2/14 3:18pm,7.0

मैं इसे पढ़ने और डेट कॉलम को डेटाइम प्रारूप में सुधार कर सकता हूं:

b=pd.read_csv('b.dat')
b['date']=pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')

मैं महीने के हिसाब से डेटा ग्रुप करने की कोशिश कर रहा हूं। ऐसा लगता है कि इस महीने तक पहुंचने और उसके द्वारा समूहीकरण करने का एक स्पष्ट तरीका होना चाहिए। लेकिन मैं ऐसा नहीं कर सकता। क्या किसी को पता है कैसे?

वर्तमान में मैं जो प्रयास कर रहा हूं, वह तिथि के अनुसार पुन: अनुक्रमण कर रहा है:

b.index=b['date']

मैं इस महीने तक पहुंच सकता हूं:

b.index.month

हालाँकि, मैं एक महीने में एक साथ गांठ करने के लिए एक समारोह खोजने के लिए प्रतीत नहीं कर सकते।

जवाबों:


174

इसके लिए प्रबंधित:

b = pd.read_csv('b.dat')
b.index = pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')
b.groupby(by=[b.index.month, b.index.year])

या

b.groupby(pd.Grouper(freq='M'))  # update for v0.21+

51
मुझे लगता है कि अधिक पैंडोनिक तरीके या तो उपयोग करने के लिए हैं resample(जब यह आपको आवश्यक कार्यक्षमता प्रदान करता है) या उपयोग करें TimeGrouper:df.groupby(pd.TimeGrouper(freq='M'))
— कार्ल डी।

10
परिणाम प्राप्त करने के लिए डाटाफ्रेम राशि या औसत, df.groupby(pd.TimeGrouper(freq='M')).sum()याdf.groupby(pd.TimeGrouper(freq='M')).mean()
— एलेक्जेंडर

9
pd.TimeGrouperके पक्ष में पदावनत किया गया है pd.Grouper, जो थोड़ा अधिक लचीला है लेकिन फिर भी तर्क freqऔर levelतर्क देता है।
— बॉलपॉइंटबैन

पहला तरीका काम नहीं करता है। यह त्रुटि देता है, 'सीरीज़ ऑब्जेक्ट की कोई विशेषता' महीना 'नहीं है, जिसके द्वारा बनाई गई श्रृंखला के लिए to_datetime।
— ely

1
@ उत्तर मूल प्रश्न में उन पंक्तियों पर निर्भर करता है जहाँ bCSV से पढ़े जाने के बाद एक सूचकांक दिया जाता है। b.index = pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')लाइन के बाद जोड़ें b = pd.read_csv('b.dat')। [मैंने अभी उत्तर भी संपादित किया है।]
— 18

71

(अपडेट: 2018)

ध्यान दें कि pd.Timegrouperमूल्यह्रास किया गया है और हटा दिया जाएगा। इसके बजाय उपयोग करें:

 df.groupby(pd.Grouper(freq='M'))

2
यहाँ ग्रॉपर डॉक्स और फ़्रीक्वेंसी स्पेसिफिकेशन ( freq=...) यहाँ खोजें । कुछ उदाहरण हैं freq=Dके लिए दिन , freq=Bके लिए व्यावसायिक दिनों , freq=Wके लिए सप्ताह या यहाँ तक कि freq=Qके लिए तिमाहियों ।
— किम

1
मैंने df को reindex करने से बचने के लिए 'key' का उपयोग करना उपयोगी पाया, इस प्रकार है: df.groupby (pd.Grouper (key = 'your_date_column', freq = 'M')
— Edward

10

एक समाधान जो मल्टीआंडेक्स से बचा जाता है, वह है एक नया datetimeकॉलम सेटिंग डे = 1. फिर इस कॉलम द्वारा समूह। नीचे दिया गया तुच्छ उदाहरण।

df = pd.DataFrame({'Date': pd.to_datetime(['2017-10-05', '2017-10-20']),
                   'Values': [5, 10]})

# normalize day to beginning of month
df['YearMonth'] = df['Date'] - pd.offsets.MonthBegin(1)

# two alternative methods
df['YearMonth'] = df['Date'] - pd.to_timedelta(df['Date'].dt.day-1, unit='D')
df['YearMonth'] = df['Date'].map(lambda dt: dt.replace(day=1))

g = df.groupby('YearMonth')

res = g['Values'].sum()

# YearMonth
# 2017-10-01    15
# Name: Values, dtype: int64

इस समाधान का सूक्ष्म लाभ है, इसके विपरीत pd.Grouper, ग्रूपर इंडेक्स को समाप्त होने के बजाय प्रत्येक महीने की शुरुआत में सामान्यीकृत किया जाता है , और इसलिए आप आसानी से समूहों को इसके माध्यम से निकाल सकते हैं get_group:

some_group = g.get_group('2017-10-01')

अक्टूबर के अंतिम दिन की गणना थोड़ा अधिक बोझिल है। pd.Grouper, v0.23 के रूप में, एक conventionपैरामीटर का समर्थन करता है , लेकिन यह केवल एक ग्रॉपर के लिए लागू होता है PeriodIndex।


8

थोड़ा वैकल्पिक समाधान @ jpp लेकिन एक YearMonthस्ट्रिंग outputting :

df['YearMonth'] = pd.to_datetime(df['Date']).apply(lambda x: '{year}-{month}'.format(year=x.year, month=x.month))

res = df.groupby('YearMonth')['Values'].sum()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.