numpy ravel对不一致的维度对象

时间:2017-10-04 12:44:17

标签: python numpy numpy-broadcasting

我有下面的代码,允许我迭代一个扁平列表并将更新映射回结构化数组 -

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

设置r [1] = 10将c [0] [1]修改为10.我想用较低的片段做类似的事情,但这失败了,我假设它是因为尺寸不一致。有没有办法获得类似的行为,所以我可以修改扁平版本而不必将其重新塑造回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 个答案:

答案 0 :(得分:1)

在您的第一种情况下,c是一个二维数组

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生成c的视图,因此对其中一个的更改会显示在另一个

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

您还可以使用cflat编制索引,效果相同:

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])

cr的这些更改不会影响原始abasarray复制这些数组。

在第二种情况下,c是包含其他数组的1d数组:

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)

这些碎片可以连接成1d阵列:

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

可以更改值,但不会影响原始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)

这会更改原始a,因为c字面上包含a,而不是其副本:

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

np.array(或asarray)尝试从输入中创建as-a-dimensional数组。在第一种情况下,输入大小相等,因此它产生2d。在第二个它们不同,所以它产生一个对象数组。此行为通常会给用户带来问题。他们要么在第二种情况下需要2d数组,要么在第一种情况下不能产生对象数组。

为了可靠地制作一个对象数组,无论输入大小是否匹配,你都必须做类似的事情

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)