简体   繁体   中英

TypeError / Array indexing; 'int' object does not support item assignment

I have a function which works on arrays with more than one item, but fails if the array contains only one item. Let's consider this example

import numpy as np

def checker(a):
   a[a>5] = np.nan

a = np.arange(10)
a = checker(a)

Works, but

a = 1
a = checker(a)   # fails

and gives

Traceback (most recent call last):
   a[a>5] = np.nan
   TypeError: 'int' object does not support item assignment

I'd like to handle it like MATLAB, and NOT like this version of checker(), which has 4x more lines than the version above.

def checker(a):
   try:
      a[a>5] = np.nan
   except TypeError:
      if a>5: a = np.nan

To create an empty array filled with nan s, you can use np.fill :

a=np.empty(np.shape(1))
a.fill(np.nan)
b=False

a[b]=10

You were getting an error because a wasn't an array, it was a float.

In MATLAB everything has atleast 2 dimensons; in numpy indexing can reduce the number of dimensions

np.shape(1)

is () ? This is the same as np.array(1).shape , ie the shape (size in MATLAB terms) of a single element array. It is 0d, as opposed to 2d in MATLAB.

a = np.empty(np.shape(1))*np.nan
# a = np.array(np.nan) does the same thing

is nan , a single element array with value nan .

a[False]

displays as array([], dtype=float) , with shape (0,) ; it's now 1d, but without any elements.

With a 0d array, the only meaningful indexing is a[()] which returns the element, nan , a np.float64 . a.item() does the same.

And for assignment purposes I can't find a way to change the value of that item

a[???] = 0   

correction, ellipsis can be used, since it stands in for any number of : including none.

a[...] = 0
# array(0,0)

(you don't wand a=0 since that just reassigns the variable).

In general 0d arrays like this are possible, but they are rarely useful.

I'm not entirely sure what you are trying to do (I don't have a working Octave session at the moment). But this difference in how dimensions change with indexing is the key to your problems.

a = np.array([np.nan])
a[np.array([False])] = 0   # no change
a[np.array([True])] = 0    # change

Note that I made the boolean index an array, but just a scalar or list. This is closer to your MATLAB boolean index.

When you multiply a scalar array by a scalar, numpy coerces the result into a scalar:

>>> a = np.empty(())
>>> a
array(10.0)
>>> a * 2
20.0

If you need to keep the scalar as an array, you can use np.asarray(a * 2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM