Numpy赋值如'numpy.take' [英] Numpy assignment like 'numpy.take'
问题描述
是否可以根据拍摄功能的工作原理分配一个numpy数组?
Is it possible to assign to a numpy array along the lines of how the take functionality works?
例如。如果我有一个数组 a
,索引列表 inds
,以及所需的轴,我可以使用take作为如下:
E.g. if I have a an array a
, a list of indices inds
, and a desired axis, I can use take as follows:
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]]
这非常有用所需的指数/轴可能会在运行时发生变化。
This is extremely useful when the indices / axis needed may change at runtime.
但是,numpy不允许你这样做:
However, numpy does not let you do this:
np.take(a, inds, axis=1) = 0
print(a)
通过 numpy.put
看起来有一些有限的(1-D)支持,但我想知道是否有更清洁的方法吗?
It looks like there is some limited (1-D) support for this via numpy.put
, but I was wondering if there was a cleaner way to do this?
推荐答案
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,:]
:
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]])
PP的建议:
PP's suggestion:
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
函数中看到了两种风格。这看起来像用于 extend_dims
,我的用于 apply_along / over_axis
。
I've seen both styles on numpy
functions. This looks like one used for extend_dims
, mine was used in apply_along/over_axis
.
在最近的拍摄
问题我/我们发现它是相当于 arr.flat [ind]
的某些raveled指数。我必须要查看它。
In a recent take
question I/we figured out that it was equivalent to arr.flat[ind]
for some some raveled index. I'll have to look that up.
有一个 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
其文档还提到地方
和 putmask
(以及 copyto
)。
Its docs also mention place
and putmask
(and copyto
).
numpy multidimensional indexing和'take'功能
我评论 take
(没有轴)相当于:
I commented take
(without axis) is equivalent to:
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]])
使用 ravel
在这种情况下是不必要的,但在其他情况下可能有用。
Use of ravel
is unecessary in this case but might useful in others.
这篇关于Numpy赋值如'numpy.take'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!