Assigning the desired number, for example, "numpy.take"

Is it possible to assign a numpy array along the lines of how accept functions work?

eg. if I have an array a, a list of indexes indsand the desired axis, I can use the following:

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 required indices / axis can change at runtime.

However, numpy does not allow you to do this:

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

There seems to be limited (1-D) support for this via numpy.put, but I was wondering if there is a cleaner way to do this?

+2
source share
3 answers
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]])

build an index tuple

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]])

Or for 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 offer:

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] raveled index. .

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 ( copyto).

numpy ""

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 , .

+3

:

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

I gave an example of using numpy.take in 2 dimensions . Perhaps you can adapt this to your problem.

0
source

Source: https://habr.com/ru/post/1015768/


All Articles