替换numpy数组中的元素以避免循环

2024-05-06 11:24:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个相当大的1d numpy数组Xold。这些值应为 根据2d numpy数组Y指定的规则替换: 例如

Xold=np.array([0,1,2,3,4])
Y=np.array([[0,0],[1,100],[3,300],[4,400],[2,200]])

当Xold中的值与Y[:,0]中的值相同时,Xnew中的新值应为Y[:,1]中的相应值。这是由两个嵌套的for循环完成的:

^{pr2}$

对于给定的示例,这将产生Xnew=[0,100,200,300,400]。 但是,对于大型数据集,此过程相当缓慢。什么是更快更优雅地完成这项任务的方法?在


Tags: 数据方法numpy示例for规则过程np
3条回答

您可以做的第一个改进是使用numpy索引,但仍有1个循环:

for old, new in Y: 
    Xold[Xold == old] = new

选择最快的方法

这个问题的答案提供了一个很好的组合方法来替换numpy数组中的元素。让我们看看,哪一个最快。在

TL;DR:Numpy索引是赢家

 def meth1(): # suggested by @Slam
    for old, new in Y:  
        Xold[Xold == old] = new

 def meth2(): # suggested by myself, convert y_dict = dict(Y) first
     [y_dict[i] if i in y_dict.keys() else i for i in Xold]

 def meth3(): # suggested by @Eelco Hoogendoom, import numpy_index as npi first
     npi.remap(Xold, keys=Y[:, 0], values=Y[:, 1])

 def meth4(): # suggested by @Brad Solomon, import pandas as pd first 
     pd.Series(Xold).map(pd.Series(Y[:, 1], index=Y[:, 0])).values

  # suggested by @jdehesa. create Xnew = Xold.copy() and index
  # idx = np.searchsorted(Xold, Y[:, 0]) first
  def meth5():             
     Xnew[idx] = Y[:, 1]

结果不足为奇

^{pr2}$

因此,好的旧列表理解是第二快的,而获胜的方法是结合searchsorted()的numpy索引。在

Y的第一列中的数据不一定排序时,我们可以将^{}用于一般情况-

sidx = Y[:,0].argsort()
out = Y[sidx[np.searchsorted(Y[:,0], Xold, sorter=sidx)],1]

样本运行-

^{pr2}$

如果不是所有元素都有相应的映射可用,那么我们需要做更多的工作,比如-

sidx = Y[:,0].argsort()
sorted_indx = np.searchsorted(Y[:,0], Xold, sorter=sidx)
sorted_indx[sorted_indx==len(sidx)] = len(sidx)-1
idx_out = sidx[sorted_indx]
out = Y[idx_out,1]
out[Y[idx_out,0]!=Xold] = 0 # NA values as 0s

相关问题 更多 >