使用ndim对ndarray进行Python numpy测试
我在用Python做一个项目,需要大量的数值数组计算。不幸的是(或者幸运的是,取决于您的POV),我对Python非常陌生,但多年来一直在做MATLAB和Octave编程(之前的APL)。我非常习惯将每个变量自动键入矩阵浮点,并且仍然习惯于检查输入类型 在我的许多函数中,我要求输入S是大小为使用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/等,另一个问题是输入可能是
(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
也会这样做,并且etssubok=True
,atleast_1D
setsndmin=1
,atleast_2d
setsndmin=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.