2014-10-30 144 views
19

我有以下數據框:熊貓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年1月,2013年2月,2013年3月等組別... 我將使用新分組數據創建一個每年/每月顯示abc vs xyz的圖。

我試過groupby和sum的各種組合,但似乎無法得到任何工作。

感謝您的協助。

回答

39

您可以使用重採樣或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

感謝您的幫助。我無法讓TimeGrouper工作,但重新採樣(「M」)完成了這個訣竅。然而,只是fyi,它需要參數how ='sum'。我現在唯一的問題是劇情正在使用滴答標籤的完整日期時間。我需要它顯示每個酒吧的月份和年份。再次感謝。 – darkpool 2014-10-30 13:58:57

7

有不同的方法來做到這一點。

  • 我創建了數據框來展示不同的技術來過濾數據。
df = pd.DataFrame({'Date':['01-Jun-13','03-Jun-13', '15-Aug-13', '20-Jan-14', '21-Feb-14'], 

'ABC':[100,-20,40,25,60], 'XYZ':[200,50,-5,15,80]})

  • 我按照你的解釋分離了幾個月/年/日和分離的月份 - 年份。
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] 
  • 我創造了新的欄目:yearmonthday和 'yearMonth'。在你的情況下,你需要兩者之一。您可以使用兩列'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 

輸出:

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([ 'YearMonth'])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 
  • 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 

您可以選擇abcxyz值列表中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 

您可以使用此工具查看您已分類爲「年 - 月」的日期,並在其上應用cretiria以獲取相關數據。

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): return s.split(「 - 」)[1] +「 - 」+ s.split(「 - 」)[2]'def getYearMonth(s): return s.split(「 - 」)[0] +「 - 」+ s.split(「 - 」)[1]'輸出'2016-08' – 2017-07-15 14:19:22

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 

那麼,如果你想保留的順序,你必須做的@ Q-人以上的建議:

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)