gpt4 book ai didi

python - 像 'numpy.take' 这样的 Numpy 赋值

转载 作者:太空狗 更新时间:2023-10-30 00:05:21 25 4
gpt4 key购买 nike

是否可以按照 take 功能的工作原理分配给 numpy 数组?

例如如果我有一个数组 a、一个索引列表 inds 和一个所需的轴,我可以按如下方式使用 take:

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) 支持,但我想知道是否有更简洁的方法来做到这一点?

最佳答案

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的建议:

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

早先的想法

在最近的一个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

它的文档还提到了 placeputmask(和 copyto)。

numpy multidimensional indexing and the function 'take'

我评论说 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]])

ravel 的使用在这种情况下是不必要的,但在其他情况下可能有用。

关于python - 像 'numpy.take' 这样的 Numpy 赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42656930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com