我正在用 Python 开发一个需要大量数值数组计算的项目。不幸的是(或者幸运的是,取决于您的 POV),我对 Python 非常陌生,但多年来一直在进行 MATLAB 和 Octave 编程(在此之前的 APL)。我非常习惯于将每个变量自动输入到矩阵浮点数中,并且仍然习惯于检查输入类型。
在我的许多函数中,我要求输入 S 是大小为 numpy.ndarray
的 (n,p)
,因此我必须测试 type(S) 是 numpy.ndarray
并获取值 (n,p) = numpy.shape(S)
。一个潜在的问题是输入可能是一个列表/元组/整数/等...,另一个问题是输入可能是一个形状为 ()
: S.ndim = 0
的数组。我突然想到我可以同时测试变量类型,修复 S.ndim = 0
问题,然后像这样得到我的维度:
# first simultaneously test for ndarray and get proper dimensions
try:
if (S.ndim == 0):
S = S.copy(); S.shape = (1,1);
# define dimensions p, and p2
(p,p2) = numpy.shape(S);
except AttributeError: # got here because input is not something array-like
raise AttributeError("blah blah blah");
虽然它有效,但我想知道这是否有效? ndim 的文档字符串说
我们当然知道 numpy 可以轻松地将 int/tuple/list 转换为数组,所以我很困惑为什么会为这些类型的输入引发 AttributeError,而 numpy 应该这样做
numpy.array(S).ndim;
哪个应该工作。
最佳答案
鉴于对@larsmans 回答的评论,您可以尝试:
if not isinstance(S, np.ndarray):
raise TypeError("Input not a ndarray")
if S.ndim == 0:
S = np.reshape(S, (1,1))
(p, p2) = S.shape
首先,您明确检查
S
是否是 ndarray
的(子类)。然后,如果需要,您可以使用 np.reshape
复制您的数据(当然还可以对其进行整形)。最后,你得到了维度。请注意,在大多数情况下,
np
函数将首先尝试访问 ndarray
的相应方法,然后尝试将输入转换为 ndarray
(有时将其保留为子类,如 np.asanyarray
,有时不是(如 np.asarray(...)
)。换句话说,使用方法而不是函数总是更有效:这就是我们使用 S.shape
而不是 np.shape(S)
的原因。另一点:
np.asarray
、 np.asanyarray
、 np.atleast_1D
...都是更通用的函数 np.array
的特殊情况。例如, asarray
将 copy
的可选 array
参数设置为 False
, asanyarray
执行相同操作并设置 subok=True
, atleast_1D
设置 ndmin=1
, atleast_2d
设置 ndmin=2
... 换句话说,使用适当的 ojit 参数总是更容易。但正如一些评论中提到的,这是一个风格问题。快捷方式通常可以提高可读性,这始终是要牢记的目标。在任何情况下,当您使用
np.array
时,您都明确要求一份初始数据的副本,有点像执行 np.array(..., copy=True)
。即使没有其他任何更改,您的数据也会被复制。这有其缺点的优点(正如我们在法语中所说的那样),例如,您可以将 list([....])
从 row-first order
更改为 column-first C
。但无论如何,你得到了你想要的副本。使用
F
,总是会创建一个新数组。如果 np.array(input, copy=False)
已经是 input
(即不浪费内存),则它将指向与 ndarray
相同的内存块,或者如果 input
不是,则将“从头开始”创建一个新的内存块。有趣的情况当然是 input
是 ndarray
。在函数中使用这个新数组可能会也可能不会改变原始输入,具体取决于函数。您必须检查要使用的函数的文档,以查看它是否返回副本。 NumPy 开发人员努力限制不必要的副本(遵循 Python 示例),但有时无法避免。文档应该明确说明会发生什么,如果没有或不清楚,请提及。
如果出现问题,
np.array(...)
可能会引发一些异常。例如,尝试将 dtype=float
与 ["STRING", 1]
之类的输入一起使用将引发 ValueError
。但是,我必须承认我不记得在所有情况下都有哪些异常(exception),请相应地编辑这篇文章。关于使用 ndim 对 ndarray 进行 Python numpy 测试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12514890/