2

連続データを任意の数の分位数にビン化する必要があります。ただし、私のアプリケーションでは、返される分位ビンの最大値が必要です。

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
4

2 に答える 2

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
于 2013-03-08T03:19:44.287 に答える
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)
于 2018-08-29T20:28:10.990 に答える