2

私はそのようなタスクに苦労しています:データフレームから列の値を離散化し、他の列の値に基づいてビン定義を行う必要があります。

最小限の作業例として、単純なデータフレームを定義しましょう。

import pandas as pd
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,'B' : np.random.randn(12)})

データフレームは次のようになります。

        A       B
0       one     2.5772143847077427
1       one     -0.6394141654096013
2       two     0.964652049995486
3       three   -0.3922889559403503
4       one     1.6903991754896424
5       one     0.5741442025742018
6       two     0.6300564981683544
7       three   0.9403680915507433
8       one     0.7044433078166983
9       one     -0.1695006646595688
10      two     0.06376190217285167
11      three   0.277540580579127

Cここで、 column の値ごとに異なるビンを持つ bin ラベルを含むcolumn を紹介したいと思いますA

  • (-10,-1,0,1,10)のためA == 'one'に、
  • (-100,0,100)のためA == 'two'に、
  • (-999,0,1,2,3)のためにA == 'three'

望ましい出力は次のとおりです。

        A       B       C
0       one     2.5772143847077427      (1, 10]
1       one     -0.6394141654096013     (-1, 0]
2       two     0.964652049995486       (0, 100]
3       three   -0.3922889559403503     (-999, 0]
4       one     1.6903991754896424      (1, 10]
5       one     0.5741442025742018      (0, 1]
6       two     0.6300564981683544      (0, 100]
7       three   0.9403680915507433      (0, 1]
8       one     0.7044433078166983      (0, 1]
9       one     -0.1695006646595688     (-1, 0]
10      two     0.06376190217285167     (0, 100]
11      three   0.277540580579127       (0, 1]

pd.cutまたはnp.digitize、 のさまざまな組み合わせを使用してみましたがmapapply成功しませんでした。

pd.cut現在、フレームを分割して各サブセットに個別に適用し、次にマージしてフレームを元に戻すことで、次のように結果を達成しています。

values_in_column_A = df['A'].unique().tolist()
bins = {'one':(-10,-1,0,1,10),'two':(-100,0,100),'three':(-999,0,1,2,3)}

def binnize(df):

    subdf = []
    for i in range(len(values_in_column_A)):
        subdf.append(df[df['A'] == values_in_column_A[i]])
        subdf[i]['C'] = pd.cut(subdf[i]['B'],bins[values_in_column_A[i]])

    return pd.concat(subdf)

これは機能しますが、十分にエレガントだとは思いません。数百万行のフレームを作成する場合、本番環境で速度やメモリの問題が発生することも予想されます。率直に言えば、これはもっとうまくできると思います。

助けやアイデアをいただければ幸いです...

4

1 に答える 1