使用ndim对ndarray进行Python numpy测试

使用ndim对ndarray进行Python numpy测试,python,arrays,numpy,Python,Arrays,Numpy,我在用Python做一个项目,需要大量的数值数组计算。不幸的是(或者幸运的是,取决于您的POV),我对Python非常陌生,但多年来一直在做MATLAB和Octave编程(之前的APL)。我非常习惯将每个变量自动键入矩阵浮点,并且仍然习惯于检查输入类型 在我的许多函数中,我要求输入S是大小为(n,p)的numpy.ndarray,因此我必须同时测试类型是numpy.ndarray,并获得值(n,p)=numpy.shape。一个潜在的问题是输入可能是列表/元组/int/等,另一个问题是输入可能是

我在用Python做一个项目,需要大量的数值数组计算。不幸的是(或者幸运的是,取决于您的POV),我对Python非常陌生,但多年来一直在做MATLAB和Octave编程(之前的APL)。我非常习惯将每个变量自动键入矩阵浮点,并且仍然习惯于检查输入类型

在我的许多函数中,我要求输入S是大小为
(n,p)
numpy.ndarray
,因此我必须同时测试类型是
numpy.ndarray
,并获得值
(n,p)=numpy.shape
。一个潜在的问题是输入可能是列表/元组/int/等,另一个问题是输入可能是形状数组
()
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的文档字符串说

如果它还不是ndarray,则需要进行转换 尝试

我们当然知道numpy可以很容易地将int/tuple/list转换为数组,所以我不明白为什么要为这些类型的输入引发AttributeError,而numpy应该这样做

numpy.array(S).ndim;

这应该可以用。

在对NumPy代码进行输入验证时,我总是使用
np.asarray

>>> np.asarray(np.array([1,2,3]))
array([1, 2, 3])
>>> np.asarray([1,2,3])
array([1, 2, 3])
>>> np.asarray((1,2,3))
array([1, 2, 3])
>>> np.asarray(1)
array(1)
>>> np.asarray(1).shape
()
这个函数有一个很好的特性,它只在必要时复制数据;如果输入已经是一个
ndarray
,则数据将保留在原位(只有类型可以更改,因为它还可以删除讨厌的
np.matrix

ndim的文档字符串说

这是函数
np.ndim
的docstring,而不是
ndim
属性,这是非NumPy对象没有的。您可以使用该函数,但其效果是数据可能会被复制两次,因此请改为:

S = np.asarray(S)
(p, p2) = S.shape
如果
S.ndim!=2


[最后一点注意:只要遵循缩进规则,就不需要Python中的
。事实上,Python程序员避免使用分号。]

给出@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.reformate
来复制您的数据(当然也可以对其进行整形)。最后,你得到了尺寸

请注意,在大多数情况下,
np
函数将首先尝试访问
ndarray
的相应方法,然后尝试将输入转换为
ndarray
(有时将其保留为子类,如
np.asanyarray
,有时则不是(如
np.asarray(…)
)换句话说,使用方法比使用函数总是更有效:这就是为什么我们使用
s.shape
,而不是
np.shape


另一点:
np.asarray
np.asanyarray
np.atleast\u 1D
…都是更通用的函数
np.array
的特殊情况。例如,
asarray
array
的可选
copy
参数设置为
False
asanyarray
也会这样做,并且ets
subok=True
atleast_1D
sets
ndmin=1
atleast_2d
sets
ndmin=2
…换句话说,使用带有适当参数的
np.array
总是比较容易的。但正如一些评论中提到的,这是一个风格问题。快捷方式通常可以提高可读性,这始终是一个问题目标要牢记在心

在任何情况下,当您使用
np.array(…,copy=True)
时,您明确地要求获得初始数据的副本,有点像执行
列表([…])
。即使没有其他更改,您的数据也会被复制。这有其缺点的优点(如我们在法语中所说)例如,您可以将
顺序
从行首
C
更改为列首
F
。但无论如何,您都可以得到所需的副本

使用
np.array(input,copy=False)
时,始终会创建一个新数组。它将指向与
input
相同的内存块(如果后者已经是
ndarray
(即没有内存浪费),或者将“从头开始”创建一个新数组如果
input
不是。有趣的例子当然是如果
input
ndarray

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


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

欢迎使用堆栈溢出。这几乎可以归结为一种样式选择,但我见过的处理这种情况的最常见方法是将输入转换为数组。Numpy provid我们已经提到了一些有用的工具。
numpy.asarray
,但这里还有一些。
numpy.asarray至少1d
类似于
asarray
,但将()数组重塑为(1,)
numpy。至少2d
与上面相同,但将0d和1d数组重塑为2d,即(3,)到(1,3)。我们转换的原因是什么“类似于数组”的数组输入部分是因为我们很懒,例如,有时很容易
>>> numpy.mean([1., 2., 3.])
>>> 2.0
Parameters
----------
a : array_like
    Array containing numbers whose mean is desired. If `a` is not an
    array, a conversion is attempted.