我已经对一个数据框进行了分组,我希望每个组可以替换某些列中的值,如果它们小于某个百分位数。
因此,一组中大于0.95百分位数的所有值应替换为0.95百分位数,所有小于0.05百分位数的值应替换为0.05百分位数。
数据框可能如下所示(示例来自another question):
两组:'一'和'两'
A B C
0 0.719391 0.091693 one
1 0.951499 0.83716 one
2 0.975212 0.224855 one
3 0.80762 0.031284 one
4 0.63319 0.342889 one
5 0.075102 0.899291 one
6 0.502843 0.773424 one
7 0.032285 0.242476 one
8 0.794938 0.607745 one
9 0.620387 0.574222 one
10 0.446639 0.549749 two
11 0.664324 0.134041 two
12 0.622217 0.505057 two
13 0.670338 0.99087 two
14 0.281431 0.016245 two
15 0.675756 0.185967 two
16 0.145147 0.045686 two
17 0.404413 0.191482 two
18 0.94913 0.943509 two
19 0.164642 0.157013 two
此数据框的结果应为:
A B C
0 0.719391 0.091693 one
1 0.951499 0.83716 one
2 0.96454115 0.224855 one
3 0.80762 0.05846805 one
4 0.63319 0.342889 one
5 0.075102 0.87133205 one
6 0.502843 0.773424 one
7 0.05155265 0.242476 one
8 0.794938 0.607745 one
9 0.620387 0.574222 one
10 0.446639 0.549749 two
11 0.664324 0.134041 two
12 0.622217 0.505057 two
13 0.670338 0.96955755 two
14 0.281431 0.02949345 two
15 0.675756 0.185967 two
16 0.15391975 0.045686 two
17 0.404413 0.191482 two
18 0.8261117 0.943509 two
19 0.164642 0.157013 two
请注意,对于A列,已替换第2,7,16和18行;对于B列,已经更换了行3,5,13和14。
有没有人知道如何以有效的方式为大型数据帧执行此操作?
由于
答案 0 :(得分:3)
您可以使用groupby
+ quantile
+ clip
:
g = df.groupby('C').transform(lambda x: x.clip(*x.quantile([0.05, 0.95])))
g['C'] = df['C']
A B C
0 0.719391 0.091693 one
1 0.951499 0.837160 one
2 0.964541 0.224855 one
3 0.807620 0.058468 one
4 0.633190 0.342889 one
5 0.075102 0.871332 one
6 0.502843 0.773424 one
7 0.051553 0.242476 one
8 0.794938 0.607745 one
9 0.620387 0.574222 one
10 0.446639 0.549749 two
11 0.664324 0.134041 two
12 0.622217 0.505057 two
13 0.670338 0.969558 two
14 0.281431 0.029493 two
15 0.675756 0.185967 two
16 0.153920 0.045686 two
17 0.404413 0.191482 two
18 0.826112 0.943509 two
19 0.164642 0.157013 two
完整性检查
np.allclose(e[['A', 'B']].values, g[['A', 'B']].values)
True
此处,e
是您问题中的输出。
答案 1 :(得分:2)
df.groupby('C')['A','B'].transform(lambda x : np.clip(x,x.quantile(0.05),x.quantile(0.95)))
Out[1599]:
A B
0 0.719391 0.091693
1 0.951499 0.837160
2 0.964541 0.224855
3 0.807620 0.058468
4 0.633190 0.342889
5 0.075102 0.871332
6 0.502843 0.773424
7 0.051553 0.242476
8 0.794938 0.607745
9 0.620387 0.574222
10 0.446639 0.549749
11 0.664324 0.134041
12 0.622217 0.505057
13 0.670338 0.969558
14 0.281431 0.029493
15 0.675756 0.185967
16 0.153920 0.045686
17 0.404413 0.191482
18 0.826112 0.943509
19 0.164642 0.157013
答案 2 :(得分:0)
要使其更快,您可以通过此方法来完成,尽管如果您有很多列,这将涉及很多编码行。这是我的数据集中包含200万行的非常快速的方法(<1s)。和您一样,.groupby非常慢!
A_05 = df['A'].quantile(0.05)
A_95 = df['A'].quantile(0.95)
df['A'].clip(A_05, A_95, inplace=True)