熊猫:具有相同名称的列的平均值

use*_*284 10 python pandas

我有一个包含以下列的数据框:

['id','name','foo1', 'foo1', 'foo1', 'foo2','foo2', 'foo3']
Run Code Online (Sandbox Code Playgroud)

我想获得一个新的数据框,其中共享相同名称的列是平均的:

['id','name','foo1', 'foo2','foo3']
Run Code Online (Sandbox Code Playgroud)

这里列foo1将是原始数据帧中名为foo1的三列的平均值,foo2将是名为foo2的两列的平均值,而foo3将只是foo3

注意:id和name不是数字,我必须保留它们.

roj*_*eer 9

基本思想是您可以按列名称进行分组,并对每个组进行操作.

我看到了一些关于你问题的评论,并试图给你不同的方法来实现这个目标.(解决方法(3)是我找到的最好的!)

(1)快速解决方案.如果您的列非常有限,且非数字,并且拥有唯一的名称,例如列idname.你能做的是:

首先设置索引['id', 'name']来保存它们,

df = df.set_index(['id', 'name']) 
Run Code Online (Sandbox Code Playgroud)

然后使用DataFrame.groupby函数on columns,set axis=1(迭代每列),mean为每个组应用函数.

df.groupby(by=df.columns, axis=1).mean()
Run Code Online (Sandbox Code Playgroud)

最后,重置索引以恢复['id', 'name']

df = df.reset_index()
Run Code Online (Sandbox Code Playgroud)

这是一个示例代码:

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
Run Code Online (Sandbox Code Playgroud)

(2)完整的解决方案.如果您有许多非数字和唯一命名的列,您可以做的是:

首先转置数据帧,

df2 = df.transpose()
Run Code Online (Sandbox Code Playgroud)

然后你按操作分组(在其索引和上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])
Run Code Online (Sandbox Code Playgroud)

最后,转换回来:

df = df2.transpose()
Run Code Online (Sandbox Code Playgroud)

这是代码示例:

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
Run Code Online (Sandbox Code Playgroud)

你需要 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])
Run Code Online (Sandbox Code Playgroud)

我尝试为未转换组处理每个组,即

df.groupby(by=df.columns, axis=1).apply(gf)
Run Code Online (Sandbox Code Playgroud)

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

我之前失败了,因为我没有小心翼翼地将轴线移开.您必须axis=1mean函数设置,并返回非数字组的列.

谢谢!