2014-03-07 23 views
0

我有一個數據框df1,其中包含有關企業的信息。每一行都是一項業務。 G列有業務編號,列R和Z(以及其他)有整數,告訴我不同​​的收入衡量標準。 A列有年份。我想創建一個新的數據框,每個業務只有一行,並且不同年份的值合起來。假設列B-Q每年不改變,但是R和Z不會改變。如何在幾年內將數據彙總到一個數據框中

爲了實現這個目標,我正在做df1.groupby("G", as_index=False)["Z"].sum()以獲得Z列的總收入。我會同樣做df1.groupby("G", as_index=False)["R"].sum()等等。

我希望最終的數據框叫df2有一行每個企業與df1所有列不會改變一年,也是新的總和列。下面的代碼是我的嘗試,但它是不正確的。問題是我不明白如何將groupby的結果添加到列。

df2['SumZ'] = df.groupby("G")["Z"].sum() 
df2['SumR'] = df.groupby("G")["R"].sum() 
df2['RZ'] =df2['SumR']/df2['SumZ'] 

一種方法是創建一個新的數據框df2與B-Q列的副本,說,然後將這些列添加到它。

如何做到這一點?我嘗試創建一個新的數據框然後添加列失敗。

這是我的完整代碼。

from __future__ import division 
import sys 
import pandas as pd 

inputfile = sys.argv[1] 
city = sys.argv[2] 
xl = pd.ExcelFile(inputfile) 

df1 = xl.parse(xl.sheet_names[0], skiprows=4,skip_footer=9) 
df1.columns = [chr(65+i) for i in xrange(len(df1.columns))] 
df1.replace('*', 3, inplace=True) 
df1 = df1.convert_objects(convert_numeric=True) 

for c in ['R', 'T', 'V', 'X', 'Z']: 
    df1[c] = df1[c].astype(int) 

for c in ['B','E', 'H', 'J', 'O', 'Q', 'S', 'U', 'W', 'Y']: 
    df1.pop(c) 
print "Read in..." 
#Now attempt and fail to make a new dataframe summarized by year  
df2['SumZ'] = df1.groupby("G", as_index=False)["Z"].sum() 
df2['SumR'] = df1.groupby("G", as_index=False)["R"].sum() 

這做什麼,我需要,但看起來非常難看。

summary_data = df1[['G', 'R','T', 'V', 'X', 'Z']].groupby('G').sum() 
constant_data = df1.drop(['R', 'T', 'V', 'X', 'Z'], axis=1).groupby('G').first() 
df2 = summary_data.join(constant_data) 

回答

2

您需要在groupby對象上調用.agg方法。 .agg代表聚合。你基本上認同這些數據爲一個單一的觀察。然後,您可以將函數字典傳遞給agg,告訴它如何處理每列。所以,想象你的數據幀是這樣的:

import pandas as pd 
import random 

df = pd.DataFrame({'business' : ['business_1', 'business_2', 'business_3', 'usiness_4', 'business_1', 'business_2', 'business_3', 'business_4'], \ 
       'years' : [2013, 2013, 2013, 2013, 2014, 2014, 2014, 2014], \ 
       'zip_code' : ['101', '102', '103', '104', '101', '102', '103', '104'], \ 
       'profit' : [random.randint(1000, 2000) for x in xrange(8)]}) 

現在「生意」就是喜歡你的id變量,ZIP_CODE是你的數據不會改變,而利潤是要總結的東西。

你已經知道用什麼函數來獲得總和,它的總和。但是你需要編寫一個函數來獲取唯一的郵政編碼值。你可以做這樣的事情:

def take_single(series): 
    return series.unique()[0] 

現在創建GROUPBY對象,創建功能的詞典要在每一列執行,並傳遞dictioanry到.agg方法(總)像這樣:

df_grouped = df.groupby('business') 
function_dict = {'business' : take_single, 'zip_code' : take_single, 'profit' : sum} 
df_grouped.agg(function_dict) 

這會得到你想要的結果,我想。

需要注意的一件事是,具有傳遞給它的聚合函數的一系列數據會自動作爲函數的第一個參數傳遞。因此,在take_single函數中,您會看到一個名爲series的參數。但是這個參數是在.agg被調用時自動傳遞的,因此不需要在函數字典中指定它。

Sum是一個內置函數,所以不需要單獨編寫它。

要重現此操作,只需使用帶有take_single值的B-Q鍵創建字典,然後使用sum函數值創建R和Z。那有意義嗎?

它不容易理解GROUPBY(我反正),但它是有用的verty ....

羅裏