Issue with true division with Numpy arrays

♀尐吖头ヾ 提交于 2020-05-13 12:21:08

问题


Suppose you have this array:

In [29]: a = array([[10, 20, 30, 40, 50], [14, 28, 42, 56, 70], [18, 36, 54, 72, 90]])

Out[30]: a
array([[ 0,  0,  0,  0,  0],
       [14, 28, 42, 56, 70],
       [18, 36, 54, 72, 90]])

Now divide the third row by the first one (using from future import division)

In [32]: a[0]/a[2]
Out[32]: array([ 0.55555556,  0.55555556,  0.55555556,  0.55555556,  0.55555556])

Now do the same with each row in a loop:

In [33]: for i in range(3):
            print a[i]/a[2]   
[ 0.55555556  0.55555556  0.55555556  0.55555556  0.55555556]
[ 0.77777778  0.77777778  0.77777778  0.77777778  0.77777778]
[ 1.  1.  1.  1.  1.]

Everything looks right. But now, assign the first array a[i]/a[2] to a[i]:

In [35]: for i in range(3):
            a[i]/=a[2]
   ....:     

In [36]: a
Out[36]: 
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1]])

Alright, no problem. Turns out this is by design. Instead, we should do:

In [38]: for i in range(3):
            a[i] = a[i]/a[2]
   ....:     

In [39]: a
Out[39]: 
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1]])

But that doesn't work. Why and how can I fix it?

Thanks in advance.


回答1:


You can cast the whole array to a float array first:

a = a.astype('float')
a /= a[2]



回答2:


"Why doesn't this work" -- The reason it doesn't work is because numpy arrays have a datatype when they're created. Any attempt to put a different type into that array will be cast to the appropriate type. In other words, when you try to put a float into your integer array, numpy casts the float to an int. The reasoning behind this is because numpy arrays are designed to be a homogonous type in order for them to have optimal performance. Put another way, they're implemented as arrays in C. And in C, you can't have an array where 1 element is a float and the next is an int. (You can have structs which behave like that, but they're not arrays).

Another solution (in addition to the one proposed by @nneonneo) is to specify the array as a float array from the beginning:

a = array([[10, 20, 30, 40, 50], [14, 28, 42, 56, 70], [18, 36, 54, 72, 90]], dtype=float)



回答3:


It's not the division that's the issue it's the assignment, ie a[i] = ... (which is also used behind the scene when you do a /= ...). Try this:

>>> a = np.zeros(3, dtype='uint8')
>>> a[:] = [2, -3, 5.9]
>>> print a
[  2 253   5]

When you do intarray[i] = floatarray[i] numpy has to truncate the floating point values to get them to fit into intarray.



来源:https://stackoverflow.com/questions/12985503/issue-with-true-division-with-numpy-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!