我有一个像下面这样的数据框架:
import numpy as np
import pandas as pd
df = pd.DataFrame({"Column1":
["A", "A", "A", "A", "B", "B", "B", "C", "C", "D"],
"Column2": [24., 25, 21., 33, 26, 24., 25, 21., 33, 26],
"Column3": [0.2, 0.3, 0.4, 0.5, 0.6, 0.2, 0.3, 0.4, 0.5, 0.6]})
Column1 Column2 Column3
0 A 24.0 0.2
1 A 25.0 0.3
2 A 21.0 0.4
3 A 33.0 0.5
4 B 26.0 0.6
5 B 24.0 0.2
6 B 25.0 0.3
7 C 21.0 0.4
8 C 33.0 0.5
9 D 26.0 0.6
这里有4行对应A, 3行对应B, 2行对应C, 1行对应d
我怎么能添加行B, C和D有相同的数字与A有4行使用他们的平均值?
例如,对于column2, B的平均值是(26+25+24)/3 = 25,对于column3, B的平均值是(0.6+0.2+0.3)/3 = 0.37
所以我添加了一行b25 0.37
对于C,只有2行,第2列和第3列的平均值分别为27和0.45
所以我添加了两行c27 0.45
对于D只有一行,所以我们用相同的值添加三行
目标是:
Column1 Column2 Column3
0 A 24.0 0.2
1 A 25.0 0.3
2 A 21.0 0.4
3 A 33.0 0.5
4 B 26.0 0.6
5 B 24.0 0.2
6 B 25.0 0.3
7 B 25.0 0.37
8 C 21.0 0.4
9 C 33.0 0.5
10 C 27.0 0.45
11 C 27.0 0.45
12 D 26.0 0.6
13 D 26.0 0.6
14 D 26.0 0.6
15 D 26.0 0.6
解决方案
g = df.groupby('Column1')
avg, s = g.mean(), g.size()
rows = avg.loc[avg.index.repeat(s.max() - s)]
pd.concat([df, rows.reset_index()]).sort_values('Column1')
解释:
计算各组mean
、size
>>> avg
Column2 Column3
Column1
A 25.75 0.350000
B 25.00 0.366667
C 27.00 0.450000
D 26.00 0.600000
>>> s
Column1
A 4
B 3
C 2
D 1
dtype: int64
Repeat
avg
数据帧的行数N次,其中N由最大组大小减去每个组的大小获得
>>> rows
Column2 Column3
Column1
B 25.0 0.366667
C 27.0 0.450000
C 27.0 0.450000
D 26.0 0.600000
D 26.0 0.600000
D 26.0 0.600000
Concat
与抽样rows
的原始数据帧,以获得具有平衡组分布的数据帧
Column1 Column2 Column3
0 A 24.0 0.200000
1 A 25.0 0.300000
2 A 21.0 0.400000
3 A 33.0 0.500000
4 B 26.0 0.600000
5 B 24.0 0.200000
6 B 25.0 0.300000
0 B 25.0 0.366667
7 C 21.0 0.400000
8 C 33.0 0.500000
1 C 27.0 0.450000
2 C 27.0 0.450000
9 D 26.0 0.600000
3 D 26.0 0.600000
4 D 26.0 0.600000
5 D 26.0 0.600000
下面是一个使用重塑的方法:
(df
.assign(idx=df.groupby('Column1').cumcount())
.pivot('idx', 'Column1')
.pipe(lambda d: d.fillna(d.mean()))
.stack()
.reset_index('Column1')
.sort_values(by='Column1')
)
输出:
Column1 Column2 Column3
idx
0 A 24.0 0.200000
1 A 25.0 0.300000
2 A 21.0 0.400000
3 A 33.0 0.500000
0 B 26.0 0.600000
1 B 24.0 0.200000
2 B 25.0 0.300000
3 B 25.0 0.366667
0 C 21.0 0.400000
1 C 33.0 0.500000
2 C 27.0 0.450000
3 C 27.0 0.450000
0 D 26.0 0.600000
1 D 26.0 0.600000
2 D 26.0 0.600000
3 D 26.0 0.600000
我想这就是你要找的。
df = pd.DataFrame({"Column1":
["A", "A", "A", "A", "B", "B", "B", "C", "C", "D"],
"Column2": [24., 25, 21., 33, 26, 24., 25, 21., 33, 26],
"Column3": [0.2, 0.3, 0.4, 0.5, 0.6, 0.2, 0.3, 0.4, 0.5, 0.6]})
# get max value
max_val = df.groupby('Column1').size().max()
# get mean for each group(A, B, C, D)
mean_df = df.groupby('Column1').mean().reset_index()
new_df = []
for col, grp in df.groupby('Column1'):
append_list = [grp]
if(len(grp) < max_val):
for i in range(max_val - len(grp)):
append_list.append(mean_df[mean_df['Column1'] == col])
new_df.append(pd.concat(append_list))
output_df = pd.concat(new_df)
output_df