【问题标题】:A way to map one array onto another in numpy?一种在numpy中将一个数组映射到另一个数组的方法?
【发布时间】:2019-02-20 00:31:56
【问题描述】:

我有一个二维数组和一个一维数组,如下所示。我想做的是用二维和一维数组的乘积填充二维数组中的空白空间 - 可能最简单的演示如下:

all_holdings = np.array([[1, 0, 0, 2, 0],
                         [2, 0, 0, 1, 0]]).astype('float64')
sub_holdings = np.array([0.2, 0.3, 0.5])

我希望得到的结果是:

array([[1. , 0.2, 0.3, 2. , 1. ],
       [2. , 0.4, 0.6, 1. , 0.5]])

即(此处显示的工作原理):

array([[1., 1*0.2, 1*0.3, 2, 2*0.5],
       [2., 2*0.2, 2*0.3, 1, 1*0.5]])

有没有人能想到一种相对快速、最好是矢量化的方法来做到这一点?我必须在多个二维数组上重复运行此计算,但始终在二维数组的同一位置使用空格。

提前(以及之后)感谢

【问题讨论】:

  • 矢量化通常具有固定成本,因此仅对大型阵列有益。是这种情况还是您的典型用例与您的示例相似?
  • 首先,我弄清楚如何做到这一点是一级迭代 - sub_holdings 的元素和 all_holdings 的相应零。将计算应用于所有行不需要循环。一旦流程定义明确且干净,您就可以担心“矢量化”了。做更多的努力可能不值得。
  • @Julien Hi - 平均而言,我将处理大约 200 个这些二维数组。
  • 数组的数量通常是无关紧要的。它们的大小(长度)是。其中 200 个似乎可以用原生循环处理。
  • @Julien - 谢谢 - hpaulj 在下面的回答是迭代的,而且看起来非常有效。

标签: python numpy array-broadcasting


【解决方案1】:
In [76]: all_holdings = np.array([[1, 0, 0, 2, 0], 
    ...:                          [2, 0, 0, 1, 0]]).astype('float64') 
    ...: sub_holdings = np.array([0.2, 0.3, 0.5])                               

只有一级迭代:

In [77]: idx = np.where(all_holdings[0,:]==0)[0]                                
In [78]: idx                                                                    
Out[78]: array([1, 2, 4])
In [79]: res = all_holdings.copy()                                              
In [80]: for i,j in zip(idx, sub_holdings): 
    ...:     res[:,i] = res[:,i-1]*j 
    ...:                                                                        
In [81]: res                                                                    
Out[81]: 
array([[1.  , 0.2 , 0.06, 2.  , 1.  ],
       [2.  , 0.4 , 0.12, 1.  , 0.5 ]])

糟糕,res[:,2] 列错误;我需要使用idx-1以外的其他东西。

现在我可以更好地想象动作。例如,所有新值是:

In [82]: res[:,idx]                                                             
Out[82]: 
array([[0.2 , 0.06, 1.  ],
       [0.4 , 0.12, 0.5 ]])

好的,我需要一种将每个 idx 值与正确的非零列正确配对的方法。

In [84]: jdx = np.where(all_holdings[0,:])[0]                                   
In [85]: jdx                                                                    
Out[85]: array([0, 3])

这并没有削减它。

但是让我们假设我们有一个正确的jdx

In [87]: jdx = np.array([0,0,3])                                                
In [88]: res = all_holdings.copy()                                              
In [89]: for i,j,v in zip(idx,jdx, sub_holdings): 
    ...:     res[:,i] = res[:,j]*v 
    ...:                                                                        
In [90]: res                                                                    
Out[90]: 
array([[1. , 0.2, 0.3, 2. , 1. ],
       [2. , 0.4, 0.6, 1. , 0.5]])
In [91]: res[:,idx]                                                             
Out[91]: 
array([[0.2, 0.3, 1. ],
       [0.4, 0.6, 0.5]])

我没有迭代就得到相同的值:

In [92]: all_holdings[:,jdx]*sub_holdings                                       
Out[92]: 
array([[0.2, 0.3, 1. ],
       [0.4, 0.6, 0.5]])

In [94]: res[:,idx] = res[:,jdx] *sub_holdings                                  
In [95]: res                                                                    
Out[95]: 
array([[1. , 0.2, 0.3, 2. , 1. ],
       [2. , 0.4, 0.6, 1. , 0.5]])

所以找到正确的jdx数组的关键。这取决于你!

【讨论】:

  • 谢谢 - 我想这大概是我们能够得到它的最快速度了。
  • 我的第一次尝试没有将非零列与sub_headings 正确配对。如果我们能找到合适的配对,我证明我们可以在没有任何迭代的情况下完成剩下的工作。
  • 是的,我注意到这可能和你在同一时间。感谢您更新它,我会弄清楚如何计算 jdx 位。
猜你喜欢
  • 1970-01-01
  • 2020-07-19
  • 2021-01-29
  • 2017-11-16
  • 2020-08-18
  • 2015-07-14
  • 2017-05-26
  • 1970-01-01
  • 2018-08-14
相关资源
最近更新 更多