根据 python 中的百分位数替换列值
Replace column values based on percentiles in python
我已经对一个数据框进行了分组,我希望每组替换某些列中的值(如果它们小于某个百分位数)。
因此,组内所有大于 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 行已被替换。
有谁知道如何有效地处理大型数据框?
谢谢
您可以使用 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
是你问题的输出。
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
为了加快速度,您可以使用此方法,但如果您有很多列,这将涉及更多的代码行。对于我的包含 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)
我已经对一个数据框进行了分组,我希望每组替换某些列中的值(如果它们小于某个百分位数)。
因此,组内所有大于 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 行已被替换。
有谁知道如何有效地处理大型数据框?
谢谢
您可以使用 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
是你问题的输出。
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
为了加快速度,您可以使用此方法,但如果您有很多列,这将涉及更多的代码行。对于我的包含 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)