Numpy赋值如'numpy.take'

时间:2017-03-07 19:41:17

标签: python arrays numpy indexing

是否可以按照拍摄功能的工作原理分配到一个numpy数组?

E.g。如果我有一个数组a,一个索引列表inds和一个所需的轴,我可以使用如下:

import numpy as np
a = np.arange(12).reshape((3, -1))
inds = np.array([1, 2])
print(np.take(a, inds, axis=1))

[[ 1  2]
 [ 5  6]
 [ 9 10]]

当所需的索引/轴在运行时可能发生变化时,这非常有用。

然而,numpy不允许你这样做:

np.take(a, inds, axis=1) = 0
print(a)

通过numpy.put看起来有一些有限的(1-D)支持,但我想知道是否有更简洁的方法来做到这一点?

3 个答案:

答案 0 :(得分:5)

import Container._

构建索引元组

In [222]: a = np.arange(12).reshape((3, -1))
     ...: inds = np.array([1, 2])
     ...: 
In [223]: np.take(a, inds, axis=1)
Out[223]: 
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10]])
In [225]: a[:,inds]
Out[225]: 
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10]])

In [226]: idx=[slice(None)]*a.ndim In [227]: axis=1 In [228]: idx[axis]=inds In [229]: a[tuple(idx)] Out[229]: array([[ 1, 2], [ 5, 6], [ 9, 10]]) In [230]: a[tuple(idx)] = 0 In [231]: a Out[231]: array([[ 0, 0, 0, 3], [ 4, 0, 0, 7], [ 8, 0, 0, 11]])

a[inds,:]

PP的建议:

In [232]: idx=[slice(None)]*a.ndim
In [233]: idx[0]=inds
In [234]: a[tuple(idx)]
Out[234]: 
array([[ 4,  0,  0,  7],
       [ 8,  0,  0, 11]])
In [235]: a[tuple(idx)]=1
In [236]: a
Out[236]: 
array([[0, 0, 0, 3],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])

def put_at(inds, axis=-1, slc=(slice(None),)): return (axis<0)*(Ellipsis,) + axis*slc + (inds,) + (-1-axis)*slc

中使用

我在a[put_at(ind_list,axis=axis)]函数中看到了这两种样式。这看起来像是用于numpy的{​​{1}},extend_dims

之前的想法

在最近的apply_along/over_axis问题中,我/我们发现它对某些某些raveled索引相当于take。我得看一下。

有一个arr.flat[ind]相当于np.put的分配:

flat

其文档还提到了Signature: np.put(a, ind, v, mode='raise') Docstring: Replaces specified elements of an array with given values. The indexing works on the flattened target array. `put` is roughly equivalent to: a.flat[ind] = v place(以及putmask)。

numpy multidimensional indexing and the function 'take'

我评论copyto(没有轴)相当于:

take

lut.flat[np.ravel_multi_index(arr.T, lut.shape)].T

ravel

并使用In [257]: a = np.arange(12).reshape((3, -1)) In [258]: IJ=np.ix_(np.arange(a.shape[0]), inds) In [259]: np.ravel_multi_index(IJ, a.shape) Out[259]: array([[ 1, 2], [ 5, 6], [ 9, 10]], dtype=int32) In [260]: np.take(a,np.ravel_multi_index(IJ, a.shape)) Out[260]: array([[ 1, 2], [ 5, 6], [ 9, 10]]) In [261]: a.flat[np.ravel_multi_index(IJ, a.shape)] = 100 In [262]: a Out[262]: array([[ 0, 100, 100, 3], [ 4, 100, 100, 7], [ 8, 100, 100, 11]])

put

在这种情况下,In [264]: np.put(a, np.ravel_multi_index(IJ, a.shape), np.arange(1,7)) In [265]: a Out[265]: array([[ 0, 1, 2, 3], [ 4, 3, 4, 7], [ 8, 5, 6, 11]]) 的使用是不必要的,但在其他情况下可能有用。

答案 1 :(得分:0)

我给出了一个使用例子 numpy.take in 2 dimensions。也许你可以适应你的问题

答案 2 :(得分:-1)

您可以通过这种方式使用索引:

a[:,[1,2]]=0