Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 连接Numpy数组而不复制_Python_Multidimensional Array_Numpy - Fatal编程技术网

Python 连接Numpy数组而不复制

Python 连接Numpy数组而不复制,python,multidimensional-array,numpy,Python,Multidimensional Array,Numpy,在Numpy中,我可以使用np.append或np.concatenate将两个数组端到端连接起来: >>> X = np.array([[1,2,3]]) >>> Y = np.array([[-1,-2,-3],[4,5,6]]) >>> Z = np.append(X, Y, axis=0) >>> Z array([[ 1, 2, 3], [-1, -2, -3], [ 4, 5,

在Numpy中,我可以使用
np.append
np.concatenate
将两个数组端到端连接起来:

>>> X = np.array([[1,2,3]])
>>> Y = np.array([[-1,-2,-3],[4,5,6]])
>>> Z = np.append(X, Y, axis=0)
>>> Z
array([[ 1,  2,  3],
       [-1, -2, -3],
       [ 4,  5,  6]])
但它们会复制它们的输入数组:

>>> Z[0,:] = 0
>>> Z
array([[ 0,  0,  0],
       [-1, -2, -3],
       [ 4,  5,  6]])
>>> X
array([[1, 2, 3]])

是否有方法将两个数组连接到一个视图中,即不复制?这需要
np.ndarray
子类吗?

属于Numpy数组的内存必须是连续的。如果单独分配阵列,它们将随机分散在内存中,并且无法将它们表示为视图Numpy阵列


如果事先知道需要多少数组,可以先从预先分配的一个大数组开始,然后让每个小数组都是大数组的视图(例如,通过切片获得)。

一点也不优雅,但使用元组存储指向数组的指针可以接近您想要的。现在我不知道我将如何在这个案例中使用它,但我以前做过类似的事情

>>> X = np.array([[1,2,3]])
>>> Y = np.array([[-1,-2,-3],[4,5,6]])
>>> z = (X, Y)
>>> z[0][:] = 0
>>> z
(array([[0, 0, 0]]), array([[-1, -2, -3],
       [ 4,  5,  6]]))
>>> X
array([[0, 0, 0]])

您可以创建一个数组,如:

>>> from numpy import *
>>> a = array([1.0, 2.0, 3.0])
>>> b = array([4.0, 5.0])
>>> c = array([a, b])
>>> c
array([[ 1.  2.  3.], [ 4.  5.]], dtype=object)
>>> a[0] = 100.0
>>> a
array([ 100.,    2.,    3.])
>>> c
array([[ 100.    2.    3.], [ 4.  5.]], dtype=object)
>>> c[0][1] = 200.0
>>> a
array([ 100.,  200.,    3.])
>>> c
array([[ 100.  200.    3.], [ 4.  5.]], dtype=object)
>>> c *= 1000
>>> c
array([[ 100000.  200000.    3000.], [ 4000.  5000.]], dtype=object)
>>> a
array([ 100.,  200.,    3.])
>>> # Oops! Copies were made...

问题是它会在广播操作中创建副本(听起来像个bug)。

在用数据填充数组之前,只需初始化数组即可。如果您愿意,您可以分配比需要更多的空间,并且不会因为numpy的工作方式而占用更多的RAM

A = np.zeros(R,C)
A[row] = [data]

只有将数据放入阵列后,才会使用内存。在任何大小的数据集(即数据集>1GB左右)上,通过连接两个数组创建新数组永远不会完成。

答案基于我在中的另一个答案


我也遇到了同样的问题,但结果是相反的,在正常连接(使用copy)后,我重新分配了原始数组,使其成为连接的数组上的视图:

import numpy as np

def concat_no_copy(arrays):
    """ Concats the arrays and returns the concatenated array 
    in addition to the original arrays as views of the concatenated one.

    Parameters:
    -----------
    arrays: list
        the list of arrays to concatenate
    """
    con = np.concatenate(arrays)

    viewarrays = []
    for i, arr in enumerate(arrays):
        arrnew = con[sum(len(a) for a in arrays[:i]):
                     sum(len(a) for a in arrays[:i + 1])]
        viewarrays.append(arrnew)
        assert all(arr == arrnew)

    # return the view arrays, replace the old ones with these
    return con, viewarrays
您可以按如下方式进行测试:

def test_concat_no_copy():
    arr1 = np.array([0, 1, 2, 3, 4])
    arr2 = np.array([5, 6, 7, 8, 9])
    arr3 = np.array([10, 11, 12, 13, 14])

    arraylist = [arr1, arr2, arr3]

    con, newarraylist = concat_no_copy(arraylist)

    assert all(con == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
                                11, 12, 13, 14]))

    for old, new in zip(arraylist, newarraylist):
        assert all(old == new)

为什么你想要一个视图而不是一个副本?@WinstonEwert:我有一个很长的数组列表,我想对其执行一次全局规范化。列表理解也会很快。这并不能回答问题,复制所有这些数组有什么错?基本上,你是担心复制的成本,还是想修改原始数组?@WinstonEwert:复制的成本是个问题;否则,我可以将它们连接起来,并将原始数组替换为连接中的视图。看起来这就是我必须要做的。无关紧要的评论:视图的内存不必是连续的,但它可能必须以固定的步幅排序(数组列表也不是这样)。你是说即使是子类也不能工作吗?我知道人们使用
ndarray
子类来处理
mmap
'd数组,但我猜内存映射也是连续的……是的,子类也必须遵循Numpy的内存模型。(@cyborgs上面的评论也是正确的:子数组也可以在内存中以固定的步幅排序,但也只能通过事先安排的方式获得。)仔细阅读may会有更多的启发。你建议切片的原因是什么,而不是例如?是的,但这不会给我我想要的那种NumPy索引魔力。无论如何谢谢你。
def test_concat_no_copy():
    arr1 = np.array([0, 1, 2, 3, 4])
    arr2 = np.array([5, 6, 7, 8, 9])
    arr3 = np.array([10, 11, 12, 13, 14])

    arraylist = [arr1, arr2, arr3]

    con, newarraylist = concat_no_copy(arraylist)

    assert all(con == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
                                11, 12, 13, 14]))

    for old, new in zip(arraylist, newarraylist):
        assert all(old == new)