【问题标题】:Problems multiplying dataframe cells by matrix values将数据框单元格乘以矩阵值的问题
【发布时间】:2019-12-15 20:36:08
【问题描述】:

Noob(试图学习 data_science)在数据框中有一个简单的投资组合。我想卖出每家公司的一定数量的股票,将卖出的股票数量乘以价格,然后加上现有的现金价值(15000),四舍五入到小数点后两位。简要介绍

new_port_df =
               Name   Price   Starting Number_of_shares
           0   MMM    10.00   50
           1   AXP    20.00   100
           2   AAPL   30.00   1000 
           3   Cash    1.00   15000

 shares_sold = [[ 5.] [ 15.] [75.] [   0.]] #(numpy.ndarray, shape (4,1))

 new_port_df['Price'] = 

           0    10.00
           1    20.00
           2    30.00
           3     1.00
           Name: Low, dtype: float64 # pandas.core.series.Series

所以基本上现金 += 5 * 10 + 15 * 20 + 75 * 30 + 0 * 1 或 15000 + 2600 = 17600

作为中间步骤(在谷歌搜索和阅读此处的其他帖子之后),我尝试过:

cash_proceeds = np.dot(shares_sold, new_port['Price'])

ValueError: shapes (4,1) and (4,) not aligned: 1 (dim 1) != 4 (dim 0). I think I should be reshaping, but haven't had any luck.  

期望的结果如下(除了 17600 单元格之外的所有工作)

updated_port_df =
               Name   Price   Starting Number_of_shares
           0   MMM    10.00   45
           1   AXP    20.00   85
           2   AAPL   30.00   925 
           3   Cash    1.00   17600 # only the 17600 not working

我能理解的简单答案优于我不能理解的复杂答案。感谢您的帮助。

【问题讨论】:

    标签: python pandas numpy dataframe reshape


    【解决方案1】:

    您可以创建一个数字列表来解决您的 np.dot() 错误,而不是将 share_sold 作为列表列表(即[[],[],[]])启动。

    shares_sold = [5,15,75,0]
    cash_proceeds = np.dot(new_port_df['Price'], shares_sold)
    

    或者正如 Andy 指出的那样,如果 share_sold 已经作为列表列表启动,您可以将其转换为数组,然后将其展平并从那里继续。我的回答不会解决随之而来的方法变化。

    然后您可以更改shares_sold 列表/数组中的最后一项,以反映出售股票的现金变化(通知保存为负数,因为这些将从您的“股份数量”列中减去):

    shares_sold[3] = -cash_proceeds
    

    现在您可以从 Number of Shares 列中减去已售出的股票以反映更改(您表示您希望 updated_port_df 包含此信息,因此我首先复制初始投资组合,然后进行更改),

    updated_port_df = new_port_df.copy()
    updated_port_df['Number_of_shares'] = updated_port_df['Number_of_shares'] - shares_sold
    

    【讨论】:

      【解决方案2】:

      您可以使用 pandas dot,而不是 np.dot。您需要一维 numpy 数组才能在系列上使用点,因此您需要将 shares_sold 转换为一维

      shares_sold = np.array([[ 5.], [ 15.], [75.] ,[   0.]])
      shares_sold_1d = shares_sold.flatten()
      
      cash_proceeds = new_port_df['Price'].dot(shares_sold_1d)
      
      In [226]: print(cash_proceeds)
      2600.0
      

      要获得所需的输出,只需使用.loc 赋值和减法

      (new_port_df.loc[new_port_df.Name.eq('Cash'), 'Starting_Number_of_shares'] = 
                    new_port_df.loc[new_port_df.Name.eq('Cash'), 'Starting_Number_of_shares'] 
                    + cash_proceeds)
      
      new_port_df['Starting_Number_of_shares'] = new_port_df['Starting_Number_of_shares'] - shares_sold_1d
      
      Out[235]:
         Name  Price  Starting_Number_of_shares
      0   MMM   10.0                       45.0
      1   AXP   20.0                       85.0
      2  AAPL   30.0                      925.0
      3  Cash    1.0                    17600.0
      

      注意:如果你真的要使用np.dot,你需要按照如下顺序交换顺序

      In [237]: np.dot(new_port_df['Price'], shares_sold)
      Out[237]: array([2600.])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 2017-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多