Numpy赋值如'numpy.take' [英] Numpy assignment like 'numpy.take'

查看:147
本文介绍了Numpy赋值如'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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆