如何返回分位切割范围的最大值而不是分位标签
我需要把连续的数据分成任意数量的分位数。不过,我的应用需要返回每个分位数的最大值:
import pandas as pd
import numpy as np
In [1]: s = pd.Series(np.random.randint(0,20,20)); s[:5]
Out[1]:
0 0
1 15
2 5
3 19
4 15
假设我使用pandas.qcut创建了5个分位数:
In [2]: bins = pd.qcut(s,5); bins
Out[2]:
Categorical:
array([[0, 1.8], (9.8, 15.2], (1.8, 6.2], (15.2, 19], (9.8, 15.2],
(1.8, 6.2], (6.2, 9.8], (6.2, 9.8], (15.2, 19], (9.8, 15.2],
[0, 1.8], (6.2, 9.8], (1.8, 6.2], [0, 1.8], (9.8, 15.2], [0, 1.8],
(15.2, 19], (15.2, 19], (6.2, 9.8], (1.8, 6.2]], dtype=object)
Levels (5): Index([[0, 1.8], (1.8, 6.2], (6.2, 9.8], (9.8, 15.2],
(15.2, 19]], dtype=object)
并且给每个分位数加上标签:
In [3]: bins.labels
Out[3]: array([0, 3, 1, 4, 3, 1, 2, 2, 4, 3, 0, 2, 1, 0, 3, 0, 4, 4, 2, 1])
我想要的不是返回分位数的编号,而是返回每个值所属的上边界。这里有一个我想要的输出示例:
original bin_max
0 0 1
1 15 15
2 5 5
3 19 19
4 15 15
5 2 5
6 7 9
7 7 9
8 16 19
9 12 15
10 0 1
11 8 9
12 5 5
13 1 1
14 11 15
15 1 1
16 18 19
17 16 19
18 9 9
19 3 5
这是我目前使用的解决方案,但我觉得在qcut上进行分组似乎效率不高,因为我需要的值已经在qcut的标签里了:
In [4]: s.groupby(pd.qcut(s,5)).transform(max)
Out[4]:
0 1
1 15
2 5
3 19
4 15
5 5
2 个回答
0
对我来说,设置 labels=False 更有效。
import pandas as pd
import numpy as np
np.random.seed(1)
s = pd.Series(np.random.randint(0,20,20))
categories, edges = pd.qcut(s, 5, retbins=True, labels=False)
df = pd.DataFrame({'original':s,
'bin_max': edges[1:][categories]},
columns = ['original', 'bin_max'])
print(df)
4
你可以使用 retbins=True
这个选项来获取分箱的边界,结果会以一个numpy数组的形式返回:
import pandas as pd
import numpy as np
np.random.seed(1)
s = pd.Series(np.random.randint(0,20,20))
categories, edges = pd.qcut(s, 5, retbins=True)
df = pd.DataFrame({'original':s,
'bin_max': edges[1:][categories.labels]},
columns = ['original', 'bin_max'])
print(df)
这样会得到
original bin_max
0 5 5.0
1 11 11.0
2 12 13.4
3 8 8.6
4 9 11.0
5 11 11.0
6 5 5.0
7 15 18.0
8 0 5.0
9 16 18.0
10 1 5.0
11 12 13.4
12 7 8.6
13 13 13.4
14 6 8.6
15 18 18.0
16 5 5.0
17 18 18.0
18 11 11.0
19 10 11.0