Вот подход, который сначала выравнивает не удаленные биты, а затем заполняет удаленные. По общему признанию, не слишком отличается от первого метода @ Divakar, но, насколько я могу сказать, немного быстрее:
Код:
import numpy as np
from simple_benchmark import BenchmarkBuilder, MultiArgument
B = BenchmarkBuilder()
@B.add_function()
def pp(b,idx,aidx):
N,n = b.size,idx.size
B = np.empty(N+n,b.dtype)
m = np.ones(N+n,bool)
m[idx] = False
B[m] = b
B[idx] = aidx
return B
@B.add_function()
def div1(b,idx,vals):
out = np.empty(len(b)+len(idx),dtype=b.dtype)
out[idx] = vals
out[np.isin(np.arange(len(out)),idx, invert=True)] = b
return out
@B.add_function()
def div2(b,idx,vals):
sidx = idx.argsort()
return np.insert(b, idx[sidx]-np.arange(len(idx)), vals[sidx])
@B.add_arguments('array size')
def argument_provider():
for exp in range(1,13):
sz = int(2**exp)
a = np.random.randint(0,100,sz*sz)
idx = np.random.choice(sz*sz,sz,replace=False)
b = np.delete(a,idx)
yield sz*sz,MultiArgument([b,idx,a[idx]])
r = B.run()
r.plot(relative_to=pp)
import pylab
import pathlib
pylab.savefig(pathlib.Path(__file__).stem + '.png')