2016-10-28 59 views
8

我有像列的數據幀:熊貓:具有相同名稱的列的平均

['id','name','foo1', 'foo1', 'foo1', 'foo2','foo2', 'foo3'] 

我想獲得一個新的數據幀,其中共享相同名稱的列的平均值:

['id','name','foo1', 'foo2','foo3'] 

這裏列foo1將是原始數據框中名爲foo1的三列的平均值,foo2將是兩列foo2的平均值,foo3將是foo3

注意:id和名稱不是數字,我必須保留它們。

+2

的ID和名稱,GROUPBY山坳名稱設置指數,均值(),重置指數應該讓 – Boud

+0

但是如果我有很多非數字列樣ID和姓名?可以通過所有非數字列設置索引嗎? – user3635284

回答

5

基本的想法是,您可以按列名稱進行分組,並對每個組進行平均操作。

我看到了一些關於你的問題的評論,並試圖給你不同的方式來實現目標。 (解決方案(3)是我發現的最好的!

(1)快速解決方案。如果列中非常有限的列是非數字列,並且擁有唯一的名稱,例如列idname。你可以做的是:

第一套指標['id', 'name']保護它們,

df = df.set_index(['id', 'name']) 

然後用DataFrame.groupby功能上columns,設置axis=1(在每列迭代),申請mean功能爲每個組。

df.groupby(by=df.columns, axis=1).mean() 

最後,重置索引恢復['id', 'name']

df = df.reset_index() 

下面是一個示例代碼:

In [35]: df = pd.DataFrame([['001', 'a', 1, 10, 100, 1000], ['002', 'b', 2, 20, 200, 2000]], columns=['id', 'name', 'c1', 'c2', 'c2', 'c3'], index=list('AB')) 

In [36]: df = df.set_index(['id', 'name']) 

In [37]: df = df.groupby(by=df.columns, axis=1).mean() 

In [38]: df = df.reset_index() 

In [39]: df 
Out[39]: 
    id name c1 c2 c3 
0 001 a 1 55 1000 
1 002 b 2 110 2000 

(2)的完整解決方案。如果你有很多是非數字和獨特命名的欄目,你可以做的是:

一轉你數據幀,

df2 = df.transpose() 

然後,通過操作做組(在其索引和axis=0) ,但仔細處理每個組:對於這些數字組,返回它們的平均值;對於這些非數字組,返回他們的第一行:

df2 = df2.groupby(by=df2.index, axis=0).apply(lambda g: g.mean() if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[0]) 

最後,轉回來:

df = df2.transpose() 

下面是代碼示例:

In [98]: df = pd.DataFrame([['001', 'a', 1, 10, 100, 1000], ['002', 'b', 2, 20, 200, 2000]], columns=['id', 'name', 'c1', 'c2', 'c2', 'c3'], index=list('AB')) 

In [99]: df2 = df.transpose() 

In [100]: df2 = df2.groupby(by=df2.index, axis=0).apply(lambda g: g.mean() if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[0]) 

In [101]: df3 = df2.transpose() 

In [102]: df3 
Out[102]: 
    c1 c2 c3 id name 
A 1 55 1000 001 a 
B 2 110 2000 002 b 

In [103]: df 
Out[103]: 
    id name c1 c2 c2 c3 
A 001 a 1 10 100 1000 
B 002 b 2 20 200 2000 

您需要import numbers

更多筆記:

(3)所有在一個!該解決方案是我找到了最好的:

df.groupby(by=df.columns, axis=1).apply(lambda g: g.mean(axis=1) if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[:,0]) 

我試圖處理每個組未置組,也就是

df.groupby(by=df.columns, axis=1).apply(gf) 

而且

gf = lambda g: g.mean(axis=1) if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[:,0] 

我失敗過,因爲我不仔細地把這個軸移動。您必須爲mean函數設置axis=1,並返回非數字組的列。

謝謝!

+0

這給了我關於 「沒有數字類型彙總」 列的錯誤是這樣的:ID:對象名稱:對象,foo1:float64,foo1:float64,foo1:float64和Foo2:float64和Foo2:float64,foo3:float64 – user3635284

+0

對於那個很抱歉。我修好了它。 – rojeeer

+0

謝謝!解決方案3真的是我需要的,檢查數據是否是數字的檢查是我無法做到的。謝謝! – user3635284