Chi*_*ken 5 python matlab numpy matrix multidimensional-array
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,:)];
Run Code Online (Sandbox Code Playgroud)
在 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)
Run Code Online (Sandbox Code Playgroud)
但这太重了。有更好的(更巧合的)方法吗?
更一般地说,我总是遇到这个问题:如果我编写了一个采用二维数组(nxk)的函数,调用它arr,其中 k 很可能是 1,那么该函数可能在一维数组上失败(例如,如果我这样做arr[0,:])。但我希望它也适用于一维数组,因为它们在道德上与其中一个维度为 1 的二维数组相同。
当然,一种出路就是放一些类似的东西
if arr.ndim == 1
arr = arr.reshape((arr.shape[0],1))
Run Code Online (Sandbox Code Playgroud)
在函数的最开始,这样就保证函数有一个二维数组可以使用。
但这并不完全令人满意。例如,我的函数可能返回与输入形状相同的数组 (nxk)。但如果输入是一维的,我希望它也返回一维的东西,而不是 (nx1)。因此,为了处理这种情况,我需要添加其他冗长的 if 语句和重塑,这将使我的代码看起来更重、更难看。
最好的出路是什么?
我认为 numpy(与 MATLAB 相比)在数组大小方面的“严格性”是一个优势,我觉得它使许多事情变得更加可预测。
\n我建议针对您的第一个问题提供以下解决方案,其中可能包含一些用于解决未来问题的有用工具。第一个工具是“省略号”( ...)对象,它可用于索引。当您在索引中看到这三个点时,您可以认为它是根据:需要替换的。例如,如果A.shape = (42,2021,69,7)thenA[..., 1, :]与 相同A[:, :, 1, :]。在这里我应该补充一点,很明显,每个索引表达式只能使用其中之一。对于编写处理任意维数数组的函数来说,这是一个非常有用的东西。
第二个(对于这个答案来说不是必需的)是您可以将其用于诸如此类的事情,np.ones您np.zeros总是具有相应的函数np.ones_like,或者np.zeros_like可以让您避免许多繁琐的计算。
因此,在下面我们使用它们首先创建一个具有正确形状的新数组,而无需执行任何算术。我们只调用np.zeros_like我们想要替换的内容(在本例中是 的最后一个“超行” A,但它可以是其中的任何一个)。同时,省略号运算符可以方便地处理我们可能存在的任意数量的维度:
import numpy as np \ndef f(A):\n u = np.zeros_like(A[-1:, ...]) # np.zeros(A[-1:, ...].shape)\n v = A[:-1,...]\n return np.concatenate([u,v], axis=0)\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
1680 次 |
| 最近记录: |