我希望以下(或类似内容)可以工作(不使用np.where)
np.where
>>> A = np.arange(0,10) >>> ind = np.logical_and(A>4, A%2) >>> k = np.array([0,1,0],dtype=bool) >>> A[ind][k] = np.pi # Doesn't actually assign to A
也就是说,我想k成为一个额外的布尔掩码,其值为indtrue。
k
ind
我知道我可以使用np.where(ind)[0][k],但这比逻辑索引更昂贵。
np.where(ind)[0][k]
有没有一种方法可以引用A[ind]基础内存A?
A[ind]
A
在经常引用的numpy索引页面中:
....单个布尔索引数组实际上与x [obj.nonzero()]相同....但是,当obj.shape == x.shape时,它会更快。
np.where(cond)是np.nonzero(cond)。
np.where(cond)
np.nonzero(cond)
但是让我们做一些简单的定时
In [239]: x = np.arange(10000) In [240]: y = (x%2).astype(bool) In [241]: x[y].shape Out[241]: (5000,) In [242]: idx = np.nonzero(y) In [243]: x[idx].shape Out[243]: (5000,) In [244]: timeit x[y].shape 89.9 µs ± 726 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) In [245]: timeit x[idx].shape 13.3 µs ± 107 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) In [246]: timeit x[np.nonzero(y)].shape 34.2 µs ± 893 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
因此,即使我们使用explicit,数组索引也比布尔索引快where。
where
A[ind][k]=不起作用,因为A[ind]它是副本,而不是视图。
A[ind][k]=
In [251]: A = np.arange(100,110) In [252]: ind = np.logical_and(A>104, A%2) In [253]: ind Out[253]: array([False, False, False, False, False, True, False, True, False, True]) In [254]: k = np.array([0,1,0], dtype=bool) In [255]: A[ind] Out[255]: array([105, 107, 109]) In [256]: A[ind][k] Out[256]: array([107]) In [257]: A[ind][k] = 12 In [258]: A Out[258]: array([100, 101, 102, 103, 104, 105, 106, 107, 108, 109])
但是使用k来从np.where(ind)作品中选择索引:
np.where(ind)
In [262]: A[np.where(ind)[0][k]]=12 In [263]: A Out[263]: array([100, 101, 102, 103, 104, 105, 106, 12, 108, 109])
获取而不是设置的时间:
In [264]: timeit A[np.where(ind)[0][k]] 1.94 µs ± 75.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [265]: timeit A[ind][k] 1.34 µs ± 13.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
因此,是的,在这种情况下,双重遮罩要快一些,但是如果不起作用,则没关系。不要浪费时间来改善时间。
In [345]: ind1=ind.copy() In [346]: ind1[ind] = k In [348]: A[ind1]=3 In [349]: A Out[349]: array([100, 101, 102, 103, 104, 105, 106, 3, 108, 109])
在这个小例子中,timeit与基本上相同A[np.where(ind)[0][k]]=12。
A[np.where(ind)[0][k]]=12