Numpy Array Division - unsupported operand type(s)

2020-07-25 01:06发布

问题:

I defined the following numpy array:

import numpy as np
numpy_array = np.array([[-1,-1,-1,-1,-1], [-1,2,2,2,-1], [-1,2,8,2,-1], [-1,2,2,2,-1], [-1,-1,-1,-1,-1,-1]])

Now I wanted to divide the whole array by 8:

numpy_array /= np.float(8.0)

I get the following error message:

TypeError: unsupported operand type(s) for /: 'list' and 'float'

I hope someone has a hint for me, what I am doing wrong.

回答1:

The array has a list of the incorrect size, the final list is incorrect.

if you want to keep the data as an int, you can use numpy_array = np.divide(numpy_array, 8.0), otherwise see MSeifert's answer.



回答2:

Unfortunatly your inner lists aren't the same size so numpy creates an object array:

>>> numpy_array
array([[-1, -1, -1, -1, -1], [-1, 2, 2, 2, -1], [-1, 2, 8, 2, -1],
       [-1, 2, 2, 2, -1], [-1, -1, -1, -1, -1, -1]], dtype=object)

You should try to avoid object arrays because they might not behave like expected and of course they are slower. If you need different sized inner lists, you should mask elements:

>>> import numpy as np
>>> numpy_array = np.array([[-1,-1,-1,-1,-1, np.nan], 
...                         [-1, 2, 2, 2,-1, np.nan], 
...                         [-1, 2, 8, 2,-1, np.nan], 
...                         [-1, 2, 2, 2,-1, np.nan], 
...                         [-1,-1,-1,-1,-1,-1]])
>>> numpy_array = np.ma.array(numpy_array, mask=np.isnan(numpy_array))
>>> numpy_array /= 8.0
>>> numpy_array
masked_array(data =
 [[-0.125 -0.125 -0.125 -0.125 -0.125 --]
 [-0.125 0.25 0.25 0.25 -0.125 --]
 [-0.125 0.25 1.0 0.25 -0.125 --]
 [-0.125 0.25 0.25 0.25 -0.125 --]
 [-0.125 -0.125 -0.125 -0.125 -0.125 -0.125]],
             mask =
 [[False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False  True]
 [False False False False False False]],
       fill_value = 1e+20)

Also you need to be careful with inplace-operations because they don't change the dtype, so when you have an integer array and in-place-divide it with a float you'll still have an integer array (with truncated results) or get an exception:

>>> arr = np.array([1, 2, 3])
>>> arr /= 8.0
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''

Create a float array instead (or cast to float or just do a normal division arr = arr / 8.0):

>>> arr = np.array([1, 2, 3], dtype=float)
>>> arr /= 8.0
>>> arr
array([ 0.125,  0.25 ,  0.375])