繁体   English   中英

保持 Numpy Arrays 2D

[英]Keep Numpy Arrays 2D

我正在做很多向量代数,并想使用 numpy arrays 来消除对循环的任何需求并运行得更快。

我发现如果我有一个大小为 [N,P] 的矩阵 A,我经常需要使用np.array([A[:,0]).T来强制A[:,0]成为大小为 (N,1) 的列向量

有没有办法将二维数组的单行或列保持为二维数组,因为它使以下算术变得更加容易。 例如,我经常需要将列向量(来自矩阵)与行向量(也从矩阵创建)相乘以创建一个新矩阵:例如

C = A[:,i] * B[j,:]

如果我不必继续使用,那就太好了:

C = np.array([A[:,i]]).T * np.array([B[j,:]])

它确实混淆了代码 - 在 MATLAB 中,它只是C = A[:,i] * B[j,:]这更容易阅读和与基础数学进行比较,特别是如果在同一行,但不幸的是,我的大多数同事都没有 MATLAB 许可证。

请注意,这不是唯一的用例,因此此列 x 行操作的特定 function 并没有太大帮助

甚至 MATLAB/Octave 也会挤出多余的维度:

>> ones(2,3,4)(:,:,1)
ans = 
   1   1   1
   1   1   1
>> size(ones(2,3,4)(1,:))       # some indexing "flattens" outer dims
ans =
    1   12

当我开始 MATLAB v3.5 2d 矩阵时,它就只有它了; 单元格、结构和更高维度是后来添加的(如上述示例所示)。

您的:

In [760]: A=np.arange(6).reshape(2,3)  
In [762]: np.array([A[:,0]]).T
Out[762]: 
array([[0],
       [3]])

比需要的更复杂。 它创建一个列表,然后是一个 (1,N) 数组,最后是一个 (N,1)

A[:,[0]]A[:,:,None]A[:,0:1]更直接。 甚至A[:,0].reshape(-1,1)

我想不出将标量和列表索引视为相同的简单方法。

np.atleast_2d这样的函数可以有条件地添加一个新维度,但它将是一个前导(外部)维度。 但是根据broadcasting的规则,领先的维度通常是“自动的”。

基本 v 高级索引

在底层 Python 中,标量不能被索引,列表只能用标量和切片来索引。 底层语法允许使用元组进行索引,但列表拒绝这些。 numpy大大扩展了索引 - 不是语法而是它如何处理这些元组。

numpy使用切片和标量进行索引是basic索引。 这就是可能发生尺寸损失的地方。 这与列表索引一致

In [768]: [[1,2,3],[4,5,6]][1]
Out[768]: [4, 5, 6]
In [769]: np.array([[1,2,3],[4,5,6]])[1]
Out[769]: array([4, 5, 6])

使用列表和 arrays 进行索引是advanced索引,没有任何列表对应项。 这可能是 MATLAB 和numpy之间的差异最丑的地方:)

 >> A([1,2],[1,2])

产生一个 (2,2) 块。 在 numpy 中产生“对角线”

In [781]: A[[0,1],[0,1]]
Out[781]: array([0, 4])

要获得块,我们必须使用相互“广播”的列表(或数组):

In [782]: A[[[0],[1]],[0,1]]      
Out[782]: 
array([[0, 1],
       [3, 4]])

要获得 MATLAB 中的“对角线”,我们必须使用sub2ind([2,2],[1,2],[1,2])来获得 [1,4] 平坦指数。

什么样的乘法?

np.array([A[:,i]]).T * np.array([B[j,:]])  

这是按元素( .* )还是矩阵?

对于 (N,1) 和 (1,M) 对, A*BA@B产生相同的 (N,M) 结果,但一个使用broadcasting来泛化outer积,另一个是内/矩阵积(与产品总和)。

https://numpy.org/doc/stable/reference/generated/numpy.matrix.html

从类似数组的 object 或从数据字符串返回矩阵。 矩阵是一个专门的二维数组,它通过操作保留其二维性质 它具有某些特殊的运算符,例如*(矩阵乘法)和**(矩阵幂)。

我不确定如何重新实现它,这是一个有趣的练习。

如前所述,矩阵将被弃用。 但是从 np.array 中,您可以使用参数 ndim=2 指定维度:

np.array([1, 2, 3], ndmin=2)

您可以通过以下方式保持维度(使用@进行矩阵乘法)

C = A[:,[i]] @ B[[j],:]

注意ij周围的括号,否则 C 将不是二维矩阵。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM