pandas 获取价值的百分位数

pandas get percentile of value withing

我有一个数据框:

d = [f1  f2  f3 
     1    2   3 
     5    1   2 
     3    3   1 
     2    4   7
     ..  ..  ..]

我想为每个特征添加行中此特征值的百分位数(对于特征子集)。 所以对于 subset = [f1,f2,f3] 我的数据框将是

new_d =[f1   f2   f3  f1_per   f2_per   f3_per
         1    2   3    0         0.25     0.5
         5    1   2    1          0       0.25
         3    3   1    0.5        0.5     0
         2    4   5    0.25      0.75     1
         4    5   4    0.75       1       0.75]

最好的方法是什么?

执行此操作的方法如下:

df['pct_1'] = df.f1.rank(pct=True) 
df['pct_f2'] = df.f2.rank(pct=True)
df['pct_f3'] = df.f3.rank(pct=True) 

给出:

   f1  f2  f3  pct_1  pct_f2  pct_f3
0   1   2   3   0.25    0.50    0.75
1   5   1   2   1.00    0.25    0.50
2   3   3   1   0.75    0.75    0.25
3   2   4   7   0.50    1.00    1.00

输出中有 5 行,输入中有 4 行,所以输出不同的是对所有列使用 DataFrame.rank 并连接回原始

df = df.join(df.rank(pct=True).add_prefix('pct'))
print (df)
  f1  f2  f3  pctf1  pctf2  pctf3
0   1   2   3    0.2    0.4    0.6
1   5   1   2    1.0    0.2    0.4
2   3   3   1    0.6    0.6    0.2
3   2   4   7    0.4    0.8    1.0
4   4   5   4    0.8    1.0    0.8

如果需要在没有 1 的情况下按行数进行百分位排名:

df = df.join(df.rank().sub(1).div(len(df) - 1).add_prefix('pct'))
print (df)
   f1  f2  f3  pctf1  pctf2  pctf3
0   1   2   3   0.00   0.25   0.50
1   5   1   2   1.00   0.00   0.25
2   3   3   1   0.50   0.50   0.00
3   2   4   7   0.25   0.75   1.00
4   4   5   4   0.75   1.00   0.75

这是另一种方法,明确地做你想做的事:

res = df.apply(lambda x: np.greater.outer(x.values, x.values).sum(axis=1) / (len(x) - 1))
res.columns = [f'{c}_per' for c in df.columns]
res = df.join(res)
print(res)

输出

   f1  f2  f3  f1_per  f2_per  f3_per
0   1   2   3    0.00    0.25    0.50
1   5   1   2    1.00    0.00    0.25
2   3   3   1    0.50    0.50    0.00
3   2   4   7    0.25    0.75    1.00
4   4   5   4    0.75    1.00    0.75