RK1
RK1

Reputation: 2532

numpy ndarray assignment not working for simple vector

I'm doing a simple conditional assignment on a slice of a numpy array below,

x = np.array([[10000, 10010,    10],[    1,     5,     3]])
idx = (x <= 100).all(axis=1)
res = np.zeros_like(x)
res[idx, :] =  (np.exp(x[idx, :]) / np.sum(np.exp(x[idx, :]), axis=1)).ravel()

In [192]: res
Out[192]: 
array([[0, 0, 0],
       [0, 0, 0]])

I expect a slice, so res[1, :] to be assigned to the values of array([0.01587624, 0.86681333, 0.11731043]), but it is not.

At first I thought it was the way I was slicing the array, but what I don't understand is if I do the following assignment it works,

res[idx, :] = np.array([1, 2, 3])

In [8]: res
Out[8]: 
array([[0, 0, 0],
       [1, 2, 3]])

Is there something simple I am missing, that my assignment doesn't work but the simple one does?

System info:

In [4]: np.__version__
Out[4]: '1.19.2'
In [6]: sys.version
Out[6]: '3.8.5 (default, Sep  4 2020, 02:22:02) \n[Clang 10.0.0 ]'

Upvotes: 1

Views: 246

Answers (1)

Askold Ilvento
Askold Ilvento

Reputation: 1510

In [58]: res.dtype
Out[58]: dtype('int64')

numpy autodetects your x array type as int and casts it to res in zeros_like. When you assign ints to res it works. When you assign floats, it rounds them, and in your case, rounds to zero.

The solution is

x = np.array(..., dtype=float)

or

res = np.zeros_like(x, dtype=float)

Upvotes: 1

Related Questions