【问题标题】:Multiplying a pd.Series vector against a multindex pd.Dataframe将 pd.Series 向量与多索引 pd.Dataframe 相乘
【发布时间】:2019-10-12 19:34:12
【问题描述】:

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

这是一个简单的例子:

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'])

此数据框表示“从 1 月到 4 月每月三种产品的价格”。分配向量表示价格的部分份额。

我想要实现的是将分配向量乘以我的数据帧,从而得到一个索引为“jan”、“feb”、“mar”、“apr”的序列,其值等于该月的点积(IE:@ 987654322@ 分别为 1 月、2 月、3 月、4 月)

我只能用讨厌的迭代hacky 解决方案来解决这个问题。我认为必须有一种更加pythonic的方式来做到这一点,而且我不必担心向量列的顺序错误,以便与数据框列等相乘。当然,实际的数据框有更多的列'不参与计算。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用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
    

    【讨论】:

      【解决方案2】:

      我相信您需要 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重塑,转置并使用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
      

      【讨论】:

        猜你喜欢
        • 2013-02-07
        • 1970-01-01
        • 2022-12-12
        • 2020-05-26
        • 2017-05-20
        • 1970-01-01
        • 2017-07-17
        • 2019-08-23
        相关资源
        最近更新 更多