Numpy广播乘法的正确语法应该是什么

时间:2021-06-03 03:57:50

标签: python pandas dataframe numpy

我需要批量计算Dataframe df,总共超过1000万行,如下:

    ts_code trade_date   open   high    low  close  pre_close  change  pct_chg        vol       amount  adj_factor
0  000001.SZ   20210602  23.89  23.92  23.38  23.89      23.92   -0.03  -0.1254  497527.02  1176608.126     111.921
1  000002.SZ   20210602  26.50  27.18  26.31  26.76      26.60    0.16   0.6015  853545.06  2287264.276     153.901
2  000004.SZ   20210602  16.21  17.18  15.92  16.57      15.98    0.59   3.6921   47125.57    77192.135       4.064
3  000005.SZ   20210602   1.80   1.83   1.77   1.80       1.79    0.01   0.5587   82388.69    14812.102       9.268
4  000006.SZ   20210602   5.29   5.29   5.22   5.24       5.28   -0.04  -0.7576   58093.43    30539.090      36.507
5  000007.SZ   20210602   3.70   3.71   3.64   3.66       3.70   -0.04  -1.0811   29560.28    10841.980       8.284
6  000008.SZ   20210602   2.27   2.29   2.27   2.28       2.28    0.00   0.0000  126807.00    28933.202      22.408
7  000009.SZ   20210602  10.00  10.09   9.89   9.92      10.05   -0.13  -1.2935  253313.77   252740.741       8.881
8  000010.SZ   20210602   4.01   4.05   4.00   4.02       4.03   -0.01  -0.2481   45925.00    18472.845      10.775
9  000011.SZ   20210602  12.86  12.90  12.42  12.52      12.97   -0.45  -3.4695   91615.92   115647.098       3.875

当我使用以下语句时,出现错误

df[['close', 'open', 'high', 'low']] = df[['close', 'open', 'high', 'low']].to_numpy() * df['adj_factor'].to_numpy()
Traceback (most recent call last):
  File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3418, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-21-f7878ae9f133>", line 1, in <module>
    df[['close', 'open', 'high', 'low']] = df[['close', 'open', 'high', 'low']].to_numpy() * df['adj_factor'].to_numpy()
ValueError: operands could not be broadcast together with shapes (11516015,4) (11516015,) 

正确的语法应该是什么?

2 个答案:

答案 0 :(得分:1)

尝试通过reshape()作为@user2357112 supports Monica评论中的提及:

df[['close', 'open', 'high', 'low']]=df[['close', 'open', 'high', 'low']].values*df['adj_factor'].values[:,None].reshape(11516015,1)

通过mul()方法

df[['close', 'open', 'high', 'low']]=df[['close', 'open', 'high', 'low']].mul(df['adj_factor'],axis=0)

答案 1 :(得分:1)

在评论和答案中以某种方式或其他方式涵盖了所有这些,但可能值得添加一些解释。

df[['close', 'open', 'high', 'low']].to_numpy() * df['adj_factor'].to_numpy()
ValueError: operands could not be broadcast together with shapes (11516015,4) (11516015,) 

数据帧是 2d 的,即 df.to_numpy() 将生成一个 2d numpy 数组。带有列列表的索引也会返回一个数据框。

df[['close', 'open', 'high', 'low']]

有 4 列,其 to_numpy()(11516015,4)

但选择一列会返回一个 Series,形状为 1d。这是 to_numpy 形状的 (11516015,)

numpy 广播的 2 个关键规则是:

  • 尝试通过添加前导维度来匹配维度
  • 调整所有尺寸 1 的尺寸以匹配

一个 (n,4) 数组可以乘以 (4,),因为后者扩展到 (1,4) 并扩展到 (n,4)。但是a(n,)只能扩展为(1,n)。

所以解决方案是将 df['adj_factor'].to_numpy() 改为 (11516015,1)

df['adj_factor'].to_numpy().reshape(-1,1)  # add trailing dimension
df['adj_factor'].to_numpy()[:,None]
df[['adj_factor']]           # list indexing