2016-10-28 57 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