繁体   English   中英

将pd.Series向量与多索引pd.Dataframe相乘

[英]Multiplying a pd.Series vector against a multindex pd.Dataframe

我有一个熊猫系列和一个熊猫多索引数据帧。

以下是一个简单的例子:

iterables = [['milk', 'honey', 'dates'], ['jan', 'feb', 'mar', 'apr']]
i = pd.MultiIndex.from_product(iterables, names=['good', 'month'])
xf = pd.DataFrame(index = i)
xf['price'] = np.random.randint(1, 25, xf.shape[0])

allocation_vector = pd.Series([0.3, 0.6, 0.1], index = ['milk', 'honey', 'dates'])

此数据框表示“每月jan到apr的三种产品的价格”.asign_vector代表价格的一小部分份额。

我想要实现的是将分配向量乘以我的数据帧,得到一系列索引'jan','feb','mar','apr'以及等于该月份dotproduct的值(IE: jan_date_price*date_pct + jan_milk_price*milk_pct + jan_honey_price*jan_pct for jan,feb,mar,apr)

我只能通过讨厌的迭代hacky解决方案来解决这个问题。 我认为必须有更多的pythonic方法来做到这一点,并且我不必担心向量列的错误顺序与数据帧列的乘法等。当然,实际的数据帧有更多的列参与计算。

我相信你需要Series.mul的第一级多个,然后按第一级求和:

np.random.seed(2019)

iterables = [['milk', 'honey', 'dates'], ['jan', 'feb', 'mar', 'apr']]
i = pd.MultiIndex.from_product(iterables, names=['good', 'month'])
xf = pd.DataFrame(index = i)
xf['price'] = np.random.randint(1, 25, xf.shape[0])
print (xf)
             price
good  month       
milk  jan        9
      feb       19
      mar        6
      apr       23
honey jan       16
      feb       13
      mar       11
      apr       17
dates jan       17
      feb        8
      mar        6
      apr       20

allocation_vector = pd.Series([0.3, 0.6, 0.1], index = ['milk', 'honey', 'dates'])

print (17*0.1+9*0.3+16*0.6)
14.0

s = xf['price'].mul(allocation_vector, level=0).sum(level=1)
print (s)
month
jan    14.0
feb    14.3
mar     9.0
apr    19.1
dtype: float64

或者通过Series.unstack重新Series.unstack ,转置并使用DataFrame.dot ,但输出中的值顺序会发生变化:

s = xf['price'].unstack().T.dot(allocation_vector)
print (s)
month
apr    19.1
feb    14.3
jan    14.0
mar     9.0
dtype: float64

您可以使用joingroupby的组合实现您想要的效果,如下所示:

allocation_vector.name = 'pct'
xf = xf.join(allocation_vector, on='good')
xf['dotproduct'] = xf.price * xf.pct

print(xf)

结果数据框是:

             price  pct  dotproduct
good  month
milk  jan       19  0.3         5.7
      feb        8  0.3         2.4
      mar        7  0.3         2.1
      apr       15  0.3         4.5
honey jan        9  0.6         5.4
      feb       10  0.6         6.0
      mar        7  0.6         4.2
      apr       11  0.6         6.6
dates jan        2  0.1         0.2
      feb       14  0.1         1.4
      mar       12  0.1         1.2
      apr        7  0.1         0.7

然后您可以使用以下方法获得所需的结果:

print(xf.groupby('month')['dotproduct'].sum())

输出是:

month
apr    11.8
feb     9.8
jan    11.3
mar     7.5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM