Я пытаюсь создать процентильные группы на фрейме данных python, который уже имеет кумулятивные процентили, основанные на нисходящих рангах. Например, мой df:
import pandas as pd
import numpy as np
data = [1.45, 1.42, 1.43, 1.41, 7.32, 1.41, 5.44, 5.49, 3.4, 7.3, 1.22, 1.9, 7.33, 7.32, 4.1, 5.48, 1.42, 3.4, 3.89, 3.9]
df = pd.DataFrame(data,columns=['values'])
df['cpctl'] = df.rank(pct=True, ascending=False)
print(df)
values cpctl
12 7.33 0.050
13 7.32 0.125
4 7.32 0.125
9 7.30 0.200
7 5.49 0.250
15 5.48 0.300
6 5.44 0.350
14 4.10 0.400
19 3.90 0.450
18 3.89 0.500
17 3.40 0.575
8 3.40 0.575
11 1.90 0.650
0 1.45 0.700
2 1.43 0.750
1 1.42 0.825
16 1.42 0.825
5 1.41 0.925
3 1.41 0.925
10 1.22 1.000
Теперь я хочу иметь возможность группировать на основе этих совокупных процентилей. В настоящее время я использую np.select для выполнения sh, но есть ли более простой способ получить следующий результат без использования np.select? Это становится утомительным, если группы создаются с шагом 1%.
conditions = [(df['cpctl']>0) & (df['cpctl']<=0.10),
(df['cpctl']>0.10) & (df['cpctl']<=0.20),
(df['cpctl']>0.20) & (df['cpctl']<=0.30),
(df['cpctl']>0.30) & (df['cpctl']<=0.40),
(df['cpctl']>0.40) & (df['cpctl']<=0.50),
(df['cpctl']>0.50) & (df['cpctl']<=0.60),
(df['cpctl']>0.60) & (df['cpctl']<=0.70),
(df['cpctl']>0.70) & (df['cpctl']<=0.80),
(df['cpctl']>0.80) & (df['cpctl']<=0.90),
(df['cpctl']>0.90) & (df['cpctl']<=1.0)]
choices = ['Top10','Top20','Top30','Top40','Top50','Top60','Top70','Top80','Top90', 'Top100']
df['groups'] = np.select(conditions, choices, default=0)
df = df.sort_values(by=['cpctl'], ascending=True)
print(df)
values cpctl groups
12 7.33 0.050 Top10
13 7.32 0.125 Top20
4 7.32 0.125 Top20
9 7.30 0.200 Top20
7 5.49 0.250 Top30
15 5.48 0.300 Top30
6 5.44 0.350 Top40
14 4.10 0.400 Top40
19 3.90 0.450 Top50
18 3.89 0.500 Top50
17 3.40 0.575 Top60
8 3.40 0.575 Top60
11 1.90 0.650 Top70
0 1.45 0.700 Top70
2 1.43 0.750 Top80
1 1.42 0.825 Top90
16 1.42 0.825 Top90
5 1.41 0.925 Top100
3 1.41 0.925 Top100
10 1.22 1.000 Top100