我有numpy数组,我想删除少量条目。之后,我想将先前的索引插入它们所属的位置。 numpy.insert不能解决问题:
import numpy
a = numpy.random.rand(7)
idx = [5, 0]
# delete some indices
b = numpy.delete(a, idx)
# magic
b /= 1.0
# insert back?
c = numpy.insert(b, idx, a[idx])
# nope :(
assert numpy.all(numpy.abs(a - c) < 1.0e-10)
有任何提示吗? (首选简单答案。)
也许有比首先使用delete更好的解决方案,例如通过切片等。
答案 0 :(得分:1)
这是array-assignment
的一种方式-
out = np.empty(len(b) + len(idx), dtype=b.dtype)
out[idx] = vals
out[np.isin(np.arange(len(out)), idx, invert=True)] = b
另一种方法涉及一些排序-
sidx = idx.argsort()
out = np.insert(b, idx[sidx] - np.arange(len(idx)), vals[sidx])
请注意,解决方案假定输入为数组。
答案 1 :(得分:1)
我认为您想做的只是用整数索引屏蔽:
import numpy as np
a = np.random.rand(7)
c = a.copy()
idx = 5, 0
# get the complement of idx
not_idx = np.fromiter((i for i in range(a.size) if i not in idx), dtype=int)
# ...or (mind the final comma: you need a `tuple` of `tuple`s):
not_idx = tuple(i for i in range(a.size) if i not in idx),
# magic
a[not_idx] /= 1.0
# yes!
assert np.all(np.abs(a - c) < 1.0e-10)
# perhaps you would prefer: `np.all(np.isclose(a, c))`?
一种更有效的方法可能是对所有内容进行“魔术”处理,然后将您想要的未修改内容复制回结果中,例如:
import numpy as np
a = np.random.rand(7)
c = a.copy()
idx = 5, 0
# magic
a /= 1.0
# copy stuff back
a[idx,] = c[idx,]
# yes!
assert np.all(np.abs(a - c) < 1.0e-10)
答案 2 :(得分:1)
这是一种方法,它首先重新排列未删除的位,然后填充已删除的位。诚然,与@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')