【发布时间】:2021-06-18 11:17:15
【问题描述】:
在 Matlab 中没有一维数组的概念。所有数组至少有两个维度。所有“向量”都是“行向量”(1xn 数组)或“列向量”(nx1 数组)。
另一方面,在 NumPy 中,数组也可以是一维的。于是就有了“纯向量”(维度n)、“行向量”(维度1xn)和“列向量”(维度nx1)的概念。
现在我正在从 Matlab 迁移到 Python,这让我很头疼。
作为一个例子,考虑我必须移动 nxk(n 通常很大,但 k 可以是 1)矩阵的行的情况,称之为 A,向下移动一行,然后添加一行零第一行。
在 Matlab 中我会这样做
[n, k] = size(A);
B = [zeros(1,k); A(1:end-1,:)];
在 Numpy 中,我希望它不仅适用于二维输入,而且适用于一维输入。 所以工作解决方案将是
import numpy as np
if A.ndim == 1:
B = np.concatenate((np.zeros(1), A[:-1]), axis=0)
if A.ndim == 2:
(n, k) = A.shape
B = np.concatenate((np.zeros((1,k)), A[:-1,:]), axis=0)
但这太重了。有没有更好(更简洁)的方法?
更一般地说,我总是遇到这个问题:如果我编写了一个采用二维数组 (nxk) 的函数,称之为arr,其中 k 很可能是 1,函数可能会在一维数组上失败(例如,如果我这样做 arr[0,:])。
但我希望它也适用于一维数组,因为它们在道德上与其中一个维度为 1 的二维数组相同。
当然,一种出路是放类似
if arr.ndim == 1
arr = arr.reshape((arr.shape[0],1))
在函数的最开始,这样就保证了函数有一个二维数组可以使用。
但这并不完全令人满意。例如,我的函数可能会返回一个与输入 (nxk) 形状相同的数组。但如果输入是一维的,我希望它也返回一维的东西,而不是 (nx1)。因此,为了处理这种情况,我需要添加其他冗长的 if 语句和整形,这会使我的代码看起来更加沉重和丑陋。
最好的出路是什么?
【问题讨论】:
-
虽然这些维度测试可能会增加代码的长度,但它们在运行时间上并没有太大的区别。您可以将该代码隐藏在函数中。
numpy函数一直在进行这样的调整。以np.atleast_2d为例,或者vstack、hstack和column_stack如何扩展基本的concatenate。像np.sum这样的函数的keep_dims参数可以很方便,以及了解使用0、[0]` 和0:1进行索引之间的区别。出于某种原因,从 MATLAB 到numpy的转换对我来说并没有那么痛苦。 -
在我阅读的时候(顺便提一下,写得很详细的问题)我打算建议你基于
reshape的方法,最后只有另一个reshape才能恢复原始数量尺寸,您最初需要将其存储在变量中 -
like it to return something one dimensional as well, not a (nx1)-.squeeze()函数末尾的额外维度。最好的出路可能是刚开始使用 Numpy 并习惯它的工作方式,除非你能找到另一个合适的包来完成你想要的。如果您正在寻求与 SO 无关的软件包/库建议。 -
@wwii “习惯 [Numpy] 的工作方式”正是我想要做的!!!如果你不这么认为,我会很高兴你告诉我一种更 NumPythonic 的思维方式!!!
-
@LuisMendo 谢谢!如果可能的话,我真的会尽量避免这种逻辑。它只会造成混乱......我敢肯定......
标签: python matlab numpy matrix multidimensional-array