在NumPy数组上调用`np.asarray'是否有大量开销?

时间:2019-06-28 10:18:50

标签: python arrays numpy

我对Python领域还很陌生,所以请原谅我的愚蠢问题。

在许多情况下,我实现了一个对类似数组的数字输入起作用的函数,使用NumPy实用程序对序列进行基本操作通常是有利的。为此,我将编写如下内容:

import numpy as np

def f(x):
    if not isinstance(x, np.ndarray):
        x = np.asarray(x)
    # and from now on we know that x is a NumPy array, with all standard methods

(请注意,我不想依赖调用方始终传递NumPy数组。)

我想知道如果通过删除if来简化代码,会带来额外的开销吗?也就是说,有类似

def f(x):
    x = np.asarray(x)
    # and from now on we know that x is a NumPy array, with all standard methods

基本上,两种情况之间的区别在于第二种代码更紧凑,但是即使np.asarray已经是NumPy数组,也将不必要地调用x

2 个答案:

答案 0 :(得分:3)

简短的回答:由于您正在使用isinstance()进行检查,因此可以使用numpy.asanyarray(),它可以无开销地通过任何ndarray及其子类。

根据numpy.asarray()的文档,当输入已经是ndarray类型时,当输入已经是数组时就没有开销:没有复制发生,它们“通过”。虽然,值得注意的是ndarray的子类没有通过。

由于在您的原始代码中使用的是isisntance(x, ndarray),因此您很可能希望numpy.asanyarray()可以通过ndarray的子类传递,这对于您的用例而言将更加有效。 (因为isinstance()对于子类也返回true)

  

返回:out:ndarray对a的数组解释。没有副本   如果输入已经是具有匹配dtype和   订购。如果a是ndarray的子​​类,则基类ndarray是   返回。

文档中的此示例(加上我自己的评论)解释了这些差异以及为什么asanyarray()更适合您的用例:

>>> issubclass(np.recarray, np.ndarray)
True   # This is to show that recarray is a subclass of ndarray
>>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
>>> np.asarray(a) is a
False  # Here a copy happens which is an overhead you don't want,
       # because the input type recarry is only a subclass of ndarray
>>> np.asanyarray(a) is a
True   # Here no copying happens, your subclass of ndarray passes through.

答案 1 :(得分:1)

看看代码,np.asarray可以做到:

array(a, dtype, copy=False, order=order)

np.asanyarray确实

array(a, dtype, copy=False, order=order, subok=True)

np.array的默认值为:

array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)