我有一个很大的1d numpy数组xold和给定的值。这些值应为
根据二维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循环完成:
Xnew=np.zeros(len(Xold))
for i in range(len(Xold)):
for j in range(len(Y)):
    if Xold[i]==Y[j,0]:
        Xnew[i]=Y[j,1]

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

最佳答案

选择最快的方法
这个问题的答案提供了一种很好的方法来替换numpy数组中的元素。让我们检查一下,哪一个最快。
tl;dr:numpy indexing是赢家

 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]

结果并不令人惊讶
 In [39]: timeit.timeit(meth1, number=1000000)
 Out[39]: 12.08

 In [40]: timeit.timeit(meth2, number=1000000)
 Out[40]: 2.87

 In [38]: timeit.timeit(meth3, number=1000000)
 Out[38]: 55.39

 In [12]: timeit.timeit(meth4, number=1000000)
 Out[12]: 256.84

 In [50]: timeit.timeit(meth5, number=1000000)
 Out[50]: 1.12

因此,良好的旧列表理解速度是第二快的,获胜的方法是numpy indexing与searchsorted()相结合。

07-28 00:54
查看更多