numpy ravel on inconsistent dimensional object

﹥>﹥吖頭↗ 提交于 2019-12-12 05:10:06

问题


I have below code that allows me to iterate over a flattened list and maps the updates back to the structured array -

a = np.asarray([1,2,3])
b = np.asarray([4,5,6])
c = np.asarray([a, b])
print c
r = c.ravel()
print r
r[1] = 10
print c

setting r[1] = 10 modifies c[0][1] to 10. I want to do something similar with the lower snippet but this fails and I am assuming it's because the dimensions are inconsistent. Is there some way to get similar behavior so I can modify a flattened version without having to reshape it back to c?

a = np.asarray([1,2,3])
b = np.asarray([4,5,6,7,8])
c = np.asarray([a, b])

r = c.ravel()
r[1] = 10
print r

回答1:


In your first case c is a 2d array

In [391]: a = np.asarray([1,2,3])
     ...: b = np.asarray([4,5,6])
     ...: c = np.asarray([a, b])
     ...: 
In [392]: c
Out[392]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [393]: c.shape
Out[393]: (2, 3)

ravel produces a view of c, so changes to one appear in the other

In [394]: r = c.ravel()
In [395]: r[1] = 10
In [396]: c
Out[396]: 
array([[ 1, 10,  3],
       [ 4,  5,  6]])

You can also index c with flat, with the same effect:

In [397]: c.flat[4] = 10
In [398]: c
Out[398]: 
array([[ 1, 10,  3],
       [ 4, 10,  6]])
In [399]: r
Out[399]: array([ 1, 10,  3,  4, 10,  6])

These changes to c or r do not affect the original a or b. asarray copies those arrays.

In the second case c is a 1d array containing other arrays:

In [400]: a = np.asarray([1,2,3])
     ...: b = np.asarray([4,5,6,7,8])
     ...: c = np.asarray([a, b])
     ...: 
In [401]: c
Out[401]: array([array([1, 2, 3]), array([4, 5, 6, 7, 8])], dtype=object)

The pieces can be joined into a 1d array:

In [402]: np.concatenate(c)
Out[402]: array([1, 2, 3, 4, 5, 6, 7, 8])

Values can be changed, but won't affect the original c.

In [403]: c[0][0] = 10
In [404]: c
Out[404]: array([array([10,  2,  3]), array([4, 5, 6, 7, 8])], dtype=object)

This changes the original a because c literally contains a, not a copy of it:

In [405]: a                     
Out[405]: array([10,  2,  3]

np.array (or asarray) tries to make as-a-dimensional array as it can from the inputs. In the first case inputs are equal in size, so it makes a 2d. In the second they differ so it makes a 1d array of objects. This behavior often gives users problems. Either they expect a 2d array in the second case, or they can't produce the object array in the first.

To reliably make an object array, regardless of whether the inputs match in size or not, you have to do something like

In [417]: g = np.empty(2, dtype=object)
In [418]: g[:] = [a, b[:3]]
In [419]: g
Out[419]: array([array([10,  2,  3]), array([4, 5, 6])], dtype=object)


来源:https://stackoverflow.com/questions/46565215/numpy-ravel-on-inconsistent-dimensional-object

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