假设我有一个像numpy那样的矩阵:
In [66]: data = np.arange(6).reshape(2,3)
In [67]: data
Out[67]:
array([[0, 1, 2],
[3, 4, 5]])
In [68]: type(data)
Out[68]: numpy.ndarray
我想得到数据[0,:]。T(应该是3乘1矩阵)和数据[1,:](应该是1乘3矩阵)的乘积,结果应该是3乘3矩阵。
所以,我写道:
M = np.dot(data[0,:].T, data[1,:])
但是这给了我一个数字而不是一个3乘3的矩阵。
我注意到在numpy.ndarray中切片给了我一个数组,因此数据[0,:]。T,data [1,:]都是3元素数组,而dot产品只是元素产品的总和。
In [92]: data[0,:].T.shape
Out[92]: (3L,)
In [93]: data[1,:].shape
Out[93]: (3L,)
In [94]: np.dot(data[0,:].T, data[1,:])
Out[94]: 14
然后,我发现我可以使用numpy.matrix将数据转换为矩阵场景,然后执行切片和点积,这是有效的。
但是,我不太确定这种转变的效率。由于我需要处理大规模矩阵,效率是我的关注点。
所以,我的问题是,对于我的情况,在切片上执行点积的最佳方法是什么?
答案 0 :(得分:3)
1x3和3x1的乘积是1x1,而不是3x3。但是,data[0, :]
和data[1, :]
都是一维数组,而不是二维矩阵。这是因为data
严格来说不是矩阵,而是二维数组。
如果你想要3x3,你必须将矩阵乘以另一个顺序(3x1乘以1x3)。你有几个方法可以做到这一点。一种是使用列表索引将行作为二维数组(有一行):
>>> np.dot(data[[1],:].T, data[[0], :])
array([[ 0, 3, 6],
[ 0, 4, 8],
[ 0, 5, 10]])
另一种可能性是使data
成为一个numpy矩阵(而不是ndarray):
data = np.matrix(data)
然后你可以更直接地进行操作:
>>> data[1, :].T * data[0, :]
matrix([[ 0, 3, 6],
[ 0, 4, 8],
[ 0, 5, 10]])
(请注意,如果使用矩阵,则可以使用*
进行矩阵乘法。)
这是因为numpy矩阵返回矩阵,即使在获得可以“挤压”到较低维度的切片时也是如此; ndarrays进行压缩,因此从2D数组中获取单行会返回1D数组,而不是1xN数组。