5

次のようなデータフレームがあります。

>>> import pandas
>>> df = pandas.DataFrame({'region' : ['east', 'west', 'south', 'west',
...  'east', 'west', 'east', 'west'],
...  'item' : ['one', 'one', 'two', 'three',
...         'two', 'two', 'one', 'three'],
...         'quantity' : [3,3,4,5,12,14,3,8], "price" : [50,50,12,35,10,10,12,12]})
>>> df
    item  price  quantity region
0    one     50         3   east
1    one     50         3   west
2    two     12         4  south
3  three     35         5   west
4    two     10        12   east
5    two     10        14   west
6    one     12         3   east
7  three     12         8   west

私がやりたいのは、数量列の値を変更することです。それぞれの新しい数量値は、この行のアイテムと価格の組み合わせに対して存在する異なる地域の数に基づいて計算されます。より具体的には、各量を取得し、領域とプールを構成する他の領域のリストを取る関数によって返されたその領域の重みを掛けたいと思います。

region_weight(region, list_of_regions). この架空の状況について、次のように言いましょう。

  • リージョン イーストは 1 の価値があります
  • 西の地域は2の価値があります
  • 南の価値は3の価値がある

次に、プールの東、西で返される東の重みは 0.3333333333333333 (1/3) です。プールの東、西、南の南の重みは 0.5 (1/2) です。

したがって、最初の行では、アイテム 1 と価格 50 の他の行があるかどうかを調べます。2 つは東地域、もう 1 つは西地域です。最初の行の新しい数量は、3 *region_weight("east", ["east", "west"]) または 3 * 0.333333333333333 になります。

全量列にも同じ処理を適用したい。データフレームを行ごとにループする以外に、pandas ライブラリでこの問題に対処する方法がわかりません。

4

1 に答える 1

4

わかりました、これはあなたが望むことだと思います:

地域の重みの辞書を作成します。

In [1]: weights = {'east':1,'west':2,'south':3}

次の関数は、Series の値を weights ディクショナリで見つかった値にマップします。 xは地域の行の値でありw、重み辞書にマップされた後の地域シリーズです。

In [2]: def f(x):
   ...:     w = x.map(weights)
   ...:     return w / w.sum().astype(float)

ここで、['item','price']上記の関数をグループ化して適用します。出力は、アイテムと価格の一意の組み合わせに対する一連の相対的な重みです。

In [3]: df.groupby(['item','price']).region.apply(f)
Out[3]:
0    0.333333
1    0.666667
2    1.000000
3    1.000000
4    0.333333
5    0.666667
6    1.000000
7    1.000000

最後にdf.quantity、上記の系列を掛けて、重量調整後の量を計算できます。

In [4]: df['wt_quant'] = df.groupby(['item','price']).region.apply(f) * df.quantity

In [5]: df
Out[5]:
    item  price  quantity region  wt_quant
0    one     50         3   east  1.000000
1    one     50         3   west  2.000000
2    two     12         4  south  4.000000
3  three     35         5   west  5.000000
4    two     10        12   east  4.000000
5    two     10        14   west  9.333333
6    one     12         3   east  3.000000
7  three     12         8   west  8.000000
于 2013-01-21T01:40:20.300 に答える