我正在用 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.asarraynp.asanyarraynp.atleast_1D ...都是更通用的函数 np.array 的特殊情况。例如, asarraycopy 的可选 array 参数设置为 Falseasanyarray 执行相同操作并设置 subok=Trueatleast_1D 设置 ndmin=1atleast_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 不是,则将“从头开始”创建一个新的内存块。有趣的情况当然是 inputndarray

在函数中使用这个新数组可能会也可能不会改变原始输入,具体取决于函数。您必须检查要使用的函数的文档,以查看它是否返回副本。 NumPy 开发人员努力限制不必要的副本(遵循 Python 示例),但有时无法避免。文档应该明确说明会发生什么,如果没有或不清楚,请提及。

如果出现问题,np.array(...) 可能会引发一些异常。例如,尝试将 dtype=float["STRING", 1] 之类的输入一起使用将引发 ValueError 。但是,我必须承认我不记得在所有情况下都有哪些异常(exception),请相应地编辑这篇文章。

关于使用 ndim 对 ndarray 进行 Python numpy 测试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12514890/

10-16 12:05