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)。

因此,对于第一行,我们看看还有哪些其他行是 item one 和 price 50。有 2 个与东部区域和一个与西部区域。第一行中的新数量为:3 *region_weight("east", ["east", "west"]) 或 3 * 0.3333333333333333。

我想对整个数量列应用相同的过程。除了逐行循环遍历 Dataframe 之外,我不知道如何使用 pandas 库来解决这个问题。

4

1 回答 1

4

好的,我认为这可以满足您的要求:

制作您的区域权重字典:

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

以下函数将 Series 中的值映射到权重字典中的值。 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 回答