2016-03-31 76 views
1

我有數據框,我去熊貓做多個列聚合。Python:在熊貓中做多個列聚合

import pandas as pd 
import numpy as np 
df = pd.DataFrame({'ser_no': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3], 
       'CTRY_NM': ['a', 'a', 'b', 'e', 'e', 'a', 'b', 'b', 'b', 'd'], 
       'lat': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 
       'long': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}) 

df2 = df.groupby(['ser_no', 'CTRY_NM']).lat.agg({'avg_lat': np.mean}) 

用此代碼,我得到的意思是lat。我也想找到long的意思。

我試圖df2 = df.groupby(['ser_no', 'CTRY_NM']).lat.agg({'avg_lat': np.mean}).long.agg({'avg_long': np.mean})但這會產生

AttributeError: 'DataFrame' object has no attribute 'long'

如果我只是做avg_long,代碼工作爲好。

df2 = df.groupby(['ser_no', 'CTRY_NM']).long.agg({'avg_long': np.mean}) 

In[2]: df2 
Out[42]: 
       avg_long 
ser_no CTRY_NM   
1  a   21.5 
     b   23.0 
2  a   26.0 
     b   27.0 
     e   24.5 
3  b   28.5 
     d   30.0 

有沒有辦法在一個步驟中做到這一點,或者這是我必須單獨做的事情,以後再回來?

回答

3

我想更多simplier是使用GroupBy.mean

print df.groupby(['ser_no', 'CTRY_NM']).mean() 
       lat long 
ser_no CTRY_NM    
1  a   1.5 21.5 
     b   3.0 23.0 
2  a   6.0 26.0 
     b   7.0 27.0 
     e   4.5 24.5 
3  b   8.5 28.5 
     d  10.0 30.0 

銥你需要定義聚集列:

更多信息在docs

編輯:

如果您需要重命名列名 - 刪除multiindexcolumns,你可以使用list comprehension

import pandas as pd 

df = pd.DataFrame({'ser_no': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3], 
       'CTRY_NM': ['a', 'a', 'b', 'e', 'e', 'a', 'b', 'b', 'b', 'd'], 
       'lat': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 
       'long': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], 
       'date':pd.date_range(pd.to_datetime('2016-02-24'), 
            pd.to_datetime('2016-02-28'), freq='10H')}) 

print df    
    CTRY_NM    date lat long ser_no 
0  a 2016-02-24 00:00:00 1 21  1 
1  a 2016-02-24 10:00:00 2 22  1 
2  b 2016-02-24 20:00:00 3 23  1 
3  e 2016-02-25 06:00:00 4 24  2 
4  e 2016-02-25 16:00:00 5 25  2 
5  a 2016-02-26 02:00:00 6 26  2 
6  b 2016-02-26 12:00:00 7 27  2 
7  b 2016-02-26 22:00:00 8 28  3 
8  b 2016-02-27 08:00:00 9 29  3 
9  d 2016-02-27 18:00:00 10 30  3    

df2=df.groupby(['ser_no','CTRY_NM']).agg({'lat':'mean','long':'mean','date':[min,max,'count']}) 
df2.columns = ['_'.join(col) for col in df2.columns] 
print df2 
       lat_mean   date_min   date_max date_count \ 
ser_no CTRY_NM                 
1  a    1.5 2016-02-24 00:00:00 2016-02-24 10:00:00   2 
     b    3.0 2016-02-24 20:00:00 2016-02-24 20:00:00   1 
2  a    6.0 2016-02-26 02:00:00 2016-02-26 02:00:00   1 
     b    7.0 2016-02-26 12:00:00 2016-02-26 12:00:00   1 
     e    4.5 2016-02-25 06:00:00 2016-02-25 16:00:00   2 
3  b    8.5 2016-02-26 22:00:00 2016-02-27 08:00:00   2 
     d   10.0 2016-02-27 18:00:00 2016-02-27 18:00:00   1 

       long_mean 
ser_no CTRY_NM    
1  a    21.5 
     b    23.0 
2  a    26.0 
     b    27.0 
     e    24.5 
3  b    28.5 
     d    30.0 
+0

我很欣賞答案,但這可能會導致問題,因爲在真實的數據集中,我有我不想表示的列。我只是在這裏製造玩具問題。 – dustin

+0

那麼如果你有更多的列,只需通過子集數據框排除它們。 – Sam

1

由於您首先選擇數據框的lat列並對該列執行操作,您會看到該錯誤。通過該系列獲取long列是不可能的,您需要數據框。

df2 = df.groupby(['ser_no', 'CTRY_NM'])["lat", "long"].agg(np.mean) 

會對兩列執行相同的操作。如果你想列名變了,你可以重命名列算賬:

df2 = df.groupby(['ser_no', 'CTRY_NM'])["lat", "long"].agg(np.mean).rename(columns = {"lat": "avg_lat", "long": "avg_long"}) 

In [22]: 
df2 = df.groupby(['ser_no', 'CTRY_NM'])["lat", "long"].agg(np.mean).rename(columns = {"lat": "avg_lat", "long": "avg_long"}) 
df2 
Out[22]: 
        avg_lat avg_long 
ser_no CTRY_NM  
1  a   1.5  21.5 
     b   3.0  23.0 
2  a   6.0  26.0 
     b   7.0  27.0 
     e   4.5  24.5 
3  b   8.5  28.5 
     d   10.0 30.0 
+0

我可以綰數據幀AGG和系列AGG?那就是,然後在一個日期列上單獨添加一個agg? – dustin

+0

如果我正確理解你,是的。 '.agg'接受一個字典,但它的工作原理與你嘗試使用的不同。每個鍵都是一列,每個值都是您想要應用於該列的功能。 ''df.groupby(['ser_no','CTRY_NM'])。agg({「lat」:np.mean,「long」:np.mean,「date」:np.max})'將平均值lat和long,但是會返回每個組的最大日期,例如。 – ayhan

+0

你理解正確,但如果到目前爲止,我想'date.agg'('{'''')''會有多個參數,或者它是有限的到一個? – dustin