np.array()和np.asarray()有什么区别?

450
什么是NumPy的np.arraynp.asarray之间的区别?我应该在什么情况下使用它们?它们似乎生成相同的输出。
8个回答

319

asarray的定义是:

def asarray(a, dtype=None, order=None):
    return array(a, dtype, copy=False, order=order)

它就像array,但选项更少,并且copy=False。默认情况下,array 的选项为 copy=True

主要区别在于,默认情况下,array 会复制对象,而asarray 只有在必要时才会。


27
那么我们在什么情况下应该使用它们?如果从头开始创建数组,哪个更好,array([1, 2, 3]) 还是 asarray([1, 2, 3]) - endolith
22
[1, 2, 3]是Python列表,因此在创建 ndarray 时必须复制数据。因此,请直接使用 np.array 而不是将 copy = False 参数发送到 np.arraynp.asarray。 如果必须进行复制,例如在此情况下,则会忽略 copy=False。如果在IPython中使用%timeit对这两种方法进行基准测试,您将会看到对于小型列表会有差异,但是对于大型列表使用哪种方法并不重要。 - unutbu
4
根据这些方法的名称,这是有道理的:"asarray":将其视为数组(原地修改),也就是说,您只是在更改对该列表/数组的查看方式。 "array":实际上将此转换为新数组。 - Jesper - jtk.eth
2
np.asanyarray 怎么样? - wsdzbm
4
@Lee: asarray总是返回一个ndarray数组。如果传递给asanyarray的参数是ndarray数组的子类,那么它将返回该子类。例如,np.matrixndarray数组的子类。因此,np.asanyarray(np.matrix(...))返回相同的矩阵,而np.asarray(np.matrix(...))将矩阵转换为一个ndarray数组。 - unutbu
显示剩余4条评论

226

由于其他关于asanyarray其他数组创建例程的问题都被重定向到这个问题,因此可能值得简要总结它们各自的作用。

它们的区别主要在于何时返回输入而不更改它,而不是制作一个作为副本的新数组。

array 提供了各种选项(大多数其它函数都只是其薄包装器),包括标志以确定何时进行复制。完整的解释将与文档一样长(请参见数组创建),但简单地说,以下是一些示例:

假设andarraymmatrix,它们都具有float32dtype

  • np.array(a)np.array(m)都会复制,因为这是默认行为。
  • np.array(a,copy=False)np.array(m,copy=False)将复制m但不会复制a,因为m不是ndarray
  • np.array(a, copy=False, subok=True)np.array(m, copy=False, subok=True) 都不会复制,因为 m 是一个 matrix,是 ndarray 的子类。
  • np.array(a, dtype=int, copy=False, subok=True) 会复制,因为 dtype 不兼容。
  • 其他大部分函数都是对 array 的薄包装,控制复制发生的时间:

    • asarray:仅当输入是相容的 ndarraycopy=False)时,才会返回未复制的输入。
    • asanyarray:仅当输入是相容的 ndarraymatrix 子类(copy=Falsesubok=True)时,才会返回未复制的输入。
    • ascontiguousarray:仅当输入是连续的 C 顺序相容 ndarraycopy=Falseorder='C')时,才会返回未复制的输入。
    • asfortranarray:如果输入是一个连续的Fortran顺序(copy=Falseorder='F')的兼容 ndarray,则返回未复制的输入。
    • require:如果输入与指定的要求字符串兼容,则返回未复制的输入。
    • copy:始终复制输入。
    • fromiter:将输入视为可迭代对象(例如,您可以从迭代器的元素构建数组,而不是从带有迭代器的元素的 object 数组);始终复制。
    • 此外还有一些方便的函数,比如asarray_chkfinite(与asarray相同的复制规则,但如果存在任何naninf值,则会引发ValueError异常),以及用于子类(如matrix)或特殊情况(如记录数组)的构造函数,当然还有实际的ndarray构造函数(它允许您直接从缓冲区的跨度创建数组)。


    仅做更正,Numpy的ndarray现在默认的dtype为float64。 - Mohith7548
    1
    在第一部分的第4点中,您实际上是指 --- np.array(a, dtype=int, copy=False, subok=True) np.array(m, dtype=int, copy=False, subok=True) 都会复制,因为 dtype 不兼容。” --- 对吗?提前致谢! - Milan

    156

    这个差异可以通过以下示例来演示:

    1. 生成一个矩阵。

     >>> A = numpy.matrix(numpy.ones((3, 3)))
     >>> A
     matrix([[ 1.,  1.,  1.],
             [ 1.,  1.,  1.],
             [ 1.,  1.,  1.]])
    
    使用numpy.array修改A。不起作用,因为您正在修改副本。
     >>> numpy.array(A)[2] = 2
     >>> A
     matrix([[ 1.,  1.,  1.],
             [ 1.,  1.,  1.],
             [ 1.,  1.,  1.]])
    
    使用numpy.asarray修改A。它起作用是因为你正在修改A本身。
     >>> numpy.asarray(A)[2] = 2
     >>> A
     matrix([[ 1.,  1.,  1.],
             [ 1.,  1.,  1.],
             [ 2.,  2.,  2.]])
    

    15
    差异在于参数列表以及函数根据这些参数的不同而产生的操作。这些差异在arrayasarray的文档中已经很清楚地提到了。
    函数定义为:
    numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
    

    numpy.asarray(a, dtype=None, order=None)
    

    以下是可以传递给array不是asarray的参数:

    copy :bool,可选项如果为true(默认),则会复制对象。否则,仅当__array__返回副本时,如果obj是嵌套序列或需要满足任何其他要求(dtype、order等),才会进行复制。

    subok :bool,可选项如果为True,则将传递子类,否则返回的数组将被强制成一个基类数组(默认)。

    ndmin :int,可选项指定结果数组应具有的最小维数。在需要满足此要求时会在形状前面添加1。


    6

    asarray(x) 类似于 array(x, copy=False)

    在进行其他操作之前,使用 asarray(x) 来确保 x 是一个数组。如果 x 已经是一个数组,则不会复制。它不会造成冗余的性能损失。

    以下是一个函数的示例,该函数确保首先将 x 转换为一个数组。

    def mysum(x):
        return np.asarray(x).sum()
    

    2

    让我们通过以下示例了解np.array()np.asarray()之间的区别:

    np.array():将输入数据(列表、元组、数组或另一序列类型)转换为ndarray,并默认复制输入数据。

    np.asarray():将输入数据转换为ndarray,但如果输入已经是ndarray,则不进行复制。

    # Create an array...
    arr = np.ones(5);  # array([1., 1., 1., 1., 1.])
    

    # Now I want to modify `arr` with `array` method. Let's see...
    np.array(arr)[3] = 200;  # array([1., 1., 1., 1., 1.])
    

    数组没有改变,因为我们修改的是数组arr的一个副本。

    现在,使用asarray()方法来修改arr

    np.asarray(arr)[3] = 200;  # array([1., 200, 1., 1., 1.])
    

    这个数组发生了变化,因为我们现在正在使用原始数组。


    1
    这是一个简单示例,可以演示区别。
    主要区别在于数组将复制原始数据,并且我们可以使用不同的对象修改原始数组中的数据。
    import numpy as np
    a = np.arange(0.0, 10.2, 0.12)
    int_cvr = np.asarray(a, dtype = np.int64)
    

    数组(a)中的内容保持不变,我们仍然可以使用另一个对象对数据进行任何操作,而无需修改原始数组中的内容。


    0

    不同之处

    1. np.array():将输入数据(如列表、元组等)转换为ndarray,并默认情况下复制输入数据。这会在内存中创建冗余对象。
    2. np.asarray():将输入数据转换为ndarray,但如果输入已经是ndarray,则不进行复制。这更节省内存。
    import numpy as np
    
    print("NumPy version:", np.__version__)
    

    NumPy version: 1.22.3
    

    案例1: 当输入为ndarray时使用np.array()

    # STEP 1: Initialize source.
    src1 = np.ones(5)
    print("Data type:", type(src1))
    print("Values:\n", src1)
    
    # STEP 2: Convert to `ndarray`.
    arr1 = np.array(src1)               # np.array() is used.
    print("\nData type:", type(arr1))
    print("Values:\n", arr1)
    
    # STEP 3: Compare source with converted `ndarray`.
    print("\nIs Source & new NumPy array same?\n", src1 is arr1)
    

    输出

    Data type: <class 'numpy.ndarray'>
    Values:
     [1. 1. 1. 1. 1.]
    
    Data type: <class 'numpy.ndarray'>
    Values:
     [1. 1. 1. 1. 1.]
    
    Is Source & new NumPy array same?
     False
    

    案例2:当输入为ndarray时使用np.asarray()。
    # STEP 1: Initialize source.
    src2 = np.ones(5)
    print("Data type:", type(src2))
    print("Values:\n", src2)
    
    # STEP 2: Convert to `ndarray`.
    arr2 = np.asarray(src2)             # np.asarray() is used.
    print("\nData type:", type(arr2))
    print("Values:\n", arr2)
    
    # STEP 3: Compare source with converted `ndarray`.
    print("\nIs Source & new NumPy array same?\n", src2 is arr2)
    

    输出

    Data type: <class 'numpy.ndarray'>
    Values:
     [1. 1. 1. 1. 1.]
    
    Data type: <class 'numpy.ndarray'>
    Values:
     [1. 1. 1. 1. 1.]
    
    Is Source & new NumPy array same?
     True
    

    因此,通过比较两个输出,我们可以得出以下结论:
    当在ndarray上使用np.asarray()时,源ndarray和转换后的ndarray指向内存中同一个对象

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接