Pandas groupby,对行求和,并将求和除以组中的行数
Pandas groupby, sum rows, and divide sum by number of rows in group
我有一个数据框:
>>> import pandas as pd
>>>
>>> df = pd.DataFrame({
... 'P': ['P1', 'P1', 'P2', 'P2', 'P2'],
... 'A1': [0,1,2,1,2],
... 'A2': [5,4,1,3,2],
... 'A3': [5,1,3,8,4],
... 'A4': [2,1,3,4,4],
... })
>>> df
P A1 A2 A3 A4
0 P1 0 5 5 2
1 P1 1 4 1 1
2 P2 2 1 3 3
3 P2 1 3 8 4
4 P2 2 2 4 4
>>>
对于每个 P,我必须对 A1-A4 列求和。比将此总和除以 P 行数。
比如每个P的行数是:
>>> df.groupby('P').size()
P
P1 2
P2 3
dtype: int64
>>>
所有列的总和为:
>>> df.groupby('P').sum()
A1 A2 A3 A4
P
P1 1 9 6 3
P2 5 6 15 11
>>>
但是因为我需要按行求和,所以我将使用:
>>> df.groupby('P').sum().sum(axis=1)
P
P1 19
P2 37
dtype: int64
>>>
现在我必须除以 19/2(大小)和 37/3 以获得我需要的结果。
为此,我会像这样准备数据:
>>> pd.concat([df.groupby('P').sum().sum(axis=1), df.groupby('P').size()], axis=1)
0 1
P
P1 19 2
P2 37 3
>>>
然后我可以使用 apply 来获得结果:
>>> pd.concat([df.groupby('P').sum().sum(axis=1), df.groupby('P').size()], axis=1).apply(lambda row: row[0]/row[1], axis=1)
P
P1 9.500000
P2 12.333333
dtype: float64
>>>
它有效,但我感觉我的计算过于复杂,无法计算每个 P 的行总和除以行数。
如果有人知道更好的方法,我会很高兴听到它。
我想至少去掉 concat。
这应该有效:
df.groupby('P').sum().sum(1) / df.groupby('P').size()
很绕的路:
(df.sum(numeric_only = True, axis = 1)
.groupby(df.P)
.pipe(lambda df: df.sum()/df.size())
)
P
P1 9.500000
P2 12.333333
dtype: float64
您可以将每个组转换为 numpy
ndarray 并一步求和所有值:
df.groupby('P').apply(lambda x: x.to_numpy().sum() / len(x))
输出:
P
P1 9.500000
P2 12.333333
我有一个数据框:
>>> import pandas as pd
>>>
>>> df = pd.DataFrame({
... 'P': ['P1', 'P1', 'P2', 'P2', 'P2'],
... 'A1': [0,1,2,1,2],
... 'A2': [5,4,1,3,2],
... 'A3': [5,1,3,8,4],
... 'A4': [2,1,3,4,4],
... })
>>> df
P A1 A2 A3 A4
0 P1 0 5 5 2
1 P1 1 4 1 1
2 P2 2 1 3 3
3 P2 1 3 8 4
4 P2 2 2 4 4
>>>
对于每个 P,我必须对 A1-A4 列求和。比将此总和除以 P 行数。 比如每个P的行数是:
>>> df.groupby('P').size()
P
P1 2
P2 3
dtype: int64
>>>
所有列的总和为:
>>> df.groupby('P').sum()
A1 A2 A3 A4
P
P1 1 9 6 3
P2 5 6 15 11
>>>
但是因为我需要按行求和,所以我将使用:
>>> df.groupby('P').sum().sum(axis=1)
P
P1 19
P2 37
dtype: int64
>>>
现在我必须除以 19/2(大小)和 37/3 以获得我需要的结果。 为此,我会像这样准备数据:
>>> pd.concat([df.groupby('P').sum().sum(axis=1), df.groupby('P').size()], axis=1)
0 1
P
P1 19 2
P2 37 3
>>>
然后我可以使用 apply 来获得结果:
>>> pd.concat([df.groupby('P').sum().sum(axis=1), df.groupby('P').size()], axis=1).apply(lambda row: row[0]/row[1], axis=1)
P
P1 9.500000
P2 12.333333
dtype: float64
>>>
它有效,但我感觉我的计算过于复杂,无法计算每个 P 的行总和除以行数。
如果有人知道更好的方法,我会很高兴听到它。 我想至少去掉 concat。
这应该有效:
df.groupby('P').sum().sum(1) / df.groupby('P').size()
很绕的路:
(df.sum(numeric_only = True, axis = 1)
.groupby(df.P)
.pipe(lambda df: df.sum()/df.size())
)
P
P1 9.500000
P2 12.333333
dtype: float64
您可以将每个组转换为 numpy
ndarray 并一步求和所有值:
df.groupby('P').apply(lambda x: x.to_numpy().sum() / len(x))
输出:
P
P1 9.500000
P2 12.333333