In [379]: M = np.arange(12).reshape(3,4)
标量索引将维度减少一。这是索引的基本规则 - 在 numpy 和 python 中。
In [380]: M[0,:]
Out[380]: array([0, 1, 2, 3])
In [381]: M[:,0]
Out[381]: array([0, 4, 8])
列表也一样:
In [383]: M.tolist()
Out[383]: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
In [384]: M.tolist()[0]
Out[384]: [0, 1, 2, 3]
带有列表/数组或切片的索引,确实保留了维度:
In [385]: M[:,[0]]
Out[385]:
array([[0],
[4],
[8]])
所以将 (3,) 分配给 (3,) 槽就可以了:
In [386]: M[:,0] = [10,20,30]
将 (3,1) 分配给该插槽会产生错误:
In [387]: M[:,0] = [[10],[20],[30]]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
<ipython-input-387-1bbfa6dfa93c> in <module>
----> 1 M[:,0] = [[10],[20],[30]]
ValueError: setting an array element with a sequence.
In [388]: M[:,0] = np.array([[10],[20],[30]]) # or with an array
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-388-6e511ffdc44e> in <module>
----> 1 M[:,0] = np.array([[10],[20],[30]])
ValueError: could not broadcast input array from shape (3,1) into shape (3)
通过广播 (3,) 可以进入 (1,3),但不能 (3,1) 进入 (3,)。一种解决方案是展平 RHS:
In [389]: M[:,0] = np.array([[10],[20],[30]]).ravel()
分配给 (3,1) 插槽也可以:
In [390]: M[:,[0]] = np.array([[10],[20],[30]])
In [391]: M[:,0:1] = np.array([[10],[20],[30]])
我们还可以将 (3,1) 转置为 (1,3)。或分配给M[:,0][:,None] 或M[:,0,None](两者都创建一个(3,1))。