2014-10-30 15 views
19

मैं निम्नलिखित dataframe है:पांडा GroupBy माह और वर्ष

Date  abc xyz 
01-Jun-13 100 200 
03-Jun-13 -20 50 
15-Aug-13 40  -5 
20-Jan-14 25  15 
21-Feb-14 60  80 

मैं वर्ष और माह से डेटा समूह की जरूरत है। यानी: जनवरी 2013, फरवरी 2013, मार्च 2013 आदि द्वारा समूह ... मैं एबीसी बनाम xyz प्रति वर्ष/माह दिखाते हुए एक साजिश बनाने के लिए नए समूह वाले डेटा का उपयोग करूँगा।

मैंने समूह और योग के विभिन्न संयोजनों की कोशिश की है लेकिन काम करने के लिए कुछ भी नहीं लग रहा है।

किसी भी सहायता के लिए धन्यवाद।

उत्तर

39

आप या तो resample या TimeGrouper (जो हुड के नीचे उपयोग का अनुकरण करता है) का उपयोग कर सकते हैं।

पहले डेटाटाइम कॉलम वास्तव में डेटाटाइम्स का है (इसे pd.to_datetime के साथ मारा गया)। अगर यह एक DatetimeIndex चाहते यह आसान है:

In [11]: df1 
Out[11]: 
      abc xyz 
Date 
2013-06-01 100 200 
2013-06-03 -20 50 
2013-08-15 40 -5 
2014-01-20 25 15 
2014-02-21 60 80 

In [12]: g = df1.groupby(pd.TimeGrouper("M"))  # DataFrameGroupBy (grouped by Month) 

In [13]: g.sum() 
Out[13]: 
      abc xyz 
Date 
2013-06-30 80 250 
2013-07-31 NaN NaN 
2013-08-31 40 -5 
2013-09-30 NaN NaN 
2013-10-31 NaN NaN 
2013-11-30 NaN NaN 
2013-12-31 NaN NaN 
2014-01-31 25 15 
2014-02-28 60 80 

In [14]: df1.resample("M", how='sum')  # the same 
Out[14]: 
      abc xyz 
Date 
2013-06-30 40 125 
2013-07-31 NaN NaN 
2013-08-31 40 -5 
2013-09-30 NaN NaN 
2013-10-31 NaN NaN 
2013-11-30 NaN NaN 
2013-12-31 NaN NaN 
2014-01-31 25 15 
2014-02-28 60 80 

मैंने सोचा था निम्नलिखित काम करेगा, लेकिन यह (कारण as_index सम्मान नहीं किया जा रहा मैं सुनिश्चित नहीं हूं?।), मैं नहीं कर रहा है इसमें दिलचस्पी के लिए भी शामिल है।

यदि यह एक स्तंभ है (! यह एक datetime64 स्तंभ होने के लिए जैसा कि मैंने कहा to_datetime के साथ मारा है,), आप PeriodIndex उपयोग कर सकते हैं:

In [21]: df 
Out[21]: 
     Date abc xyz 
0 2013-06-01 100 200 
1 2013-06-03 -20 50 
2 2013-08-15 40 -5 
3 2014-01-20 25 15 
4 2014-02-21 60 80 

In [22]: pd.DatetimeIndex(df.Date).to_period("M") # old way 
Out[22]: 
<class 'pandas.tseries.period.PeriodIndex'> 
[2013-06, ..., 2014-02] 
Length: 5, Freq: M 

In [23]: per = df.Date.dt.to_period("M") # new way to get the same 

In [24]: g = df.groupby(per) 

In [25]: g.sum() # dang not quite what we want (doesn't fill in the gaps) 
Out[25]: 
     abc xyz 
2013-06 80 250 
2013-08 40 -5 
2014-01 25 15 
2014-02 60 80 

वांछित परिणाम हम पुन: अनुक्रमणिका के लिए है पाने के लिए। ..

+0

के आउटपुट प्राप्त करने के लिए धन्यवाद। मुझे टाइमग्रापर काम करने के लिए नहीं मिला, लेकिन फिर से नमूना ("एम") चाल चल रहा था। हालांकि सिर्फ fyi, यह तर्क की आवश्यकता है कि कैसे = 'योग'। मेरी एकमात्र समस्या यह है कि साजिश टिक लेबल के लिए पूर्ण डेटाटाइम का उपयोग कर रही है। मुझे बस प्रत्येक बार के लिए महीने और साल दिखाने की ज़रूरत है। एक बार फिर धन्यवाद। – darkpool

7

ऐसा करने के कई तरीके हैं।

  • मैंने आपके डेटा को फ़िल्टर करने के लिए विभिन्न तकनीकों को प्रदर्शित करने के लिए डेटा फ्रेम बनाया है।
df = pd.DataFrame({'Date':['01-Jun-13','03-Jun-13', '15-Aug-13', '20-Jan-14', '21-Feb-14'], 

'एबीसी': [100, -20,40,25,60], 'xyz': [200,50, -5,15,80]})

  • मैंने महीनों/वर्ष/दिन और अलग-अलग महीने-वर्ष अलग किए जैसा आपने समझाया। year, month, day और 'yearMonth':
def getMonth(s): 
    return s.split("-")[1] 

def getDay(s): 
    return s.split("-")[0] 

def getYear(s): 
    return s.split("-")[2] 

def getYearMonth(s): 
    return s.split("-")[1]+"-"+s.split("-")[2] 
  • मैं नए कॉलम बनाया। आपके मामले में, आपको दोनों में से एक की आवश्यकता है। आप दो कॉलम 'year','month' या का उपयोग करते हुए समूह एक स्तंभ yearMonth
का उपयोग कर सकते हैं
df['year']= df['Date'].apply(lambda x: getYear(x)) 
df['month']= df['Date'].apply(lambda x: getMonth(x)) 
df['day']= df['Date'].apply(lambda x: getDay(x)) 
df['YearMonth']= df['Date'].apply(lambda x: getYearMonth(x)) 

आउटपुट:

 Date abc xyz year month day YearMonth 
0 01-Jun-13 100 200 13 Jun 01 Jun-13 
1 03-Jun-13 -20 50 13 Jun 03 Jun-13 
2 15-Aug-13 40 -5 13 Aug 15 Aug-13 
3 20-Jan-14 25 15 14 Jan 20 Jan-14 
4 21-Feb-14 60 80 14 Feb 21 Feb-14 
  • आप GroupBy में विभिन्न समूहों के माध्यम से जा सकते हैं (..) आइटम ।

इस मामले में, हम दो कॉलम द्वारा समूहीकरण रहे हैं:

for key,g in df.groupby(['year','month']): 
    print key,g 

आउटपुट:

('13', 'Jun')   Date abc xyz year month day YearMonth 
0 01-Jun-13 100 200 13 Jun 01 Jun-13 
1 03-Jun-13 -20 50 13 Jun 03 Jun-13 
('13', 'Aug')   Date abc xyz year month day YearMonth 
2 15-Aug-13 40 -5 13 Aug 15 Aug-13 
('14', 'Jan')   Date abc xyz year month day YearMonth 
3 20-Jan-14 25 15 14 Jan 20 Jan-14 
('14', 'Feb')   Date abc xyz year month day YearMonth 

इस मामले में, हम एक स्तंभ द्वारा समूहीकरण रहे हैं:

for key,g in df.groupby(['YearMonth']): 
    print key,g 
012 । ([ 'वर्ष महीना']) get_group

Jun-13   Date abc xyz year month day YearMonth 
0 01-Jun-13 100 200 13 Jun 01 Jun-13 
1 03-Jun-13 -20 50 13 Jun 03 Jun-13 
Aug-13   Date abc xyz year month day YearMonth 
2 15-Aug-13 40 -5 13 Aug 15 Aug-13 
Jan-14   Date abc xyz year month day YearMonth 
3 20-Jan-14 25 15 14 Jan 20 Jan-14 
Feb-14   Date abc xyz year month day YearMonth 
4 21-Feb-14 60 80 14 Feb 21 Feb-14 
  • मामले में आप विशिष्ट आइटम के लिए करना चाहते हैं का उपयोग कर सकते हैं, तो आप get_group

प्रिंट df.groupby उपयोग कर सकते हैं:

आउटपुट ('जून -13')

आउटपुट:

 Date abc xyz year month day YearMonth 
0 01-Jun-13 100 200 13 Jun 01 Jun-13 
1 03-Jun-13 -20 50 13 Jun 03 Jun-13 
  • get_group की ही तरह। यह हैक मूल्यों को फ़िल्टर करने और समूहित मान प्राप्त करने में मदद करेगा।

यह भी वही परिणाम देगा।

print df[df['YearMonth']=='Jun-13'] 

आउटपुट:

 Date abc xyz year month day YearMonth 
0 01-Jun-13 100 200 13 Jun 01 Jun-13 
1 03-Jun-13 -20 50 13 Jun 03 Jun-13 

आप abc या xyz मानों की सूची का चयन कर सकते दौरान Jun-13

print df[df['YearMonth']=='Jun-13'].abc.values 
print df[df['YearMonth']=='Jun-13'].xyz.values 

आउटपुट:

[100 -20] #abc values 
[200 50] #xyz values 

आप इस तारीख का उपयोग उन तिथियों के माध्यम से करने के लिए कर सकते हैं जिन्हें आपने "वर्ष-महीने" के रूप में वर्गीकृत किया है और संबंधित डेटा प्राप्त करने के लिए क्रिटिरिया लागू करते हैं।

for x in set(df.YearMonth): 
    print df[df['YearMonth']==x].abc.values 
    print df[df['YearMonth']==x].xyz.values 

मैं इस answer की जांच करने के साथ ही यह भी सुझाव है।

+0

जिनकी तिथियां हैं यह प्रारूप '2016-08-11', बदलें 'def getYearMonth: वापसी s.split (" - ") [1] +" - "+ s.split (" - ") [2]' def getYearMonth (0): वापसी s.split ("-") [0] + "-" + s.split ("-") [1] '' 2016-08' –

23

इसे आसान क्यों न रखें ?!

GB=DF.groupby([(DF.index.year),(DF.index.month)]).sum() 

आप वर्ष और माह के साथ एक स्ट्रिंग स्तंभ बनाने के रूप में निम्नानुसार द्वारा

print(GB) 
     abc xyz 
2013 6 80 250 
    8 40 -5 
2014 1 25 15 
    2 60 80 

दे रही है, और फिर आप का उपयोग कर पूछा की तरह प्लॉट कर सकते हैं,

GB.plot('abc','xyz',kind='scatter') 
0

तुम भी यह कर सकते हैं :

df['date'] = df.index 
df['year-month'] = df['date'].apply(lambda x: str(x.year) + ' ' + str(x.month)) 
grouped = df.groupby('year-month') 

हालांकि जब आप समूहों पर लूप करते हैं तो यह ऑर्डर को सुरक्षित नहीं करता है, उदा।

for name, group in grouped: 
    print(name) 

देना होगा:

2007 11 
2007 12 
2008 1 
2008 10 
2008 11 
2008 12 
2008 2 
2008 3 
2008 4 
2008 5 
2008 6 
2008 7 
2008 8 
2008 9 
2009 1 
2009 10 

तो फिर, यदि आप आदेश सुरक्षित रखना चाहते हैं, तो आप क्या करना चाहिए के रूप में द्वारा @ क्यू आदमी से ऊपर का सुझाव दिया:

grouped = df.groupby([df.index.year, df.index.month]) 

यह सुरक्षित करेगा उपर्युक्त लूप में ऑर्डर:

(2007, 11) 
(2007, 12) 
(2008, 1) 
(2008, 2) 
(2008, 3) 
(2008, 4) 
(2008, 5) 
(2008, 6) 
(2008, 7) 
(2008, 8) 
(2008, 9) 
(2008, 10) 
संबंधित मुद्दे