【问题标题】:Repeat NumPy array without replicating data?重复 NumPy 数组而不复制数据?
【发布时间】:2011-07-30 15:55:08
【问题描述】:

我想创建一个 1D NumPy 数组,该数组由另一个 1D 数组的 1000 次背靠背重复组成,而不复制数据 1000 次。

有可能吗?

如果有帮助,我打算将这两个数组都视为不可变的。

【问题讨论】:

  • 我在尝试在 Python 中搜索大数据操作后遇到了这个问题。我读到了关于 Strides 的文章,想知道为什么需要一个基本相同的复制数据(指向内存中的相同数据)。您可以从单个数据集读取两次,不是吗?我只想知道您进行此复制的原因。谢谢。

标签: python numpy memory large-data


【解决方案1】:

broadcast_to 是在 numpy 1.10 中添加的,它可以让您更轻松地有效地重复数组。

复制已接受答案的样式:

import numpy as np
arr = np.arange(10)
repeated = np.broadcast_to(arr, (1000, arr.size))

【讨论】:

    【解决方案2】:

    你不能这样做; NumPy 数组在每个维度上必须具有一致的步幅,而您的步幅在大多数情况下需要向一个方向前进,但有时会向后跳跃。

    您可以获得的最接近的是 1000 行二维数组,其中每一行都是您的第一个数组的视图,或者是 flatiter object,其行为类似于一维数组。 (flatiters 支持迭代和索引,但您不能查看它们;所有索引都会复制。)

    设置:

    import numpy as np
    a = np.arange(10)
    

    二维视图:

    b = np.lib.stride_tricks.as_strided(a, (1000, a.size), (0, a.itemsize))
    

    扁平化对象:

    c = b.flat
    

    【讨论】:

    • 酷,我想知道是否可以使用 strides,但我不知道如何使用! b.flatb.flatten()?
    • b.flat.base is b 为真; b.flatten().base is b 是 False,所以你想要 b.flat
    • 不确定这意味着什么。 b.flatten().base 什么都不返回...(b.flat == b.flatten()).all() 是 True,那么有什么区别?
    • docs.scipy.org/doc/numpy/reference/generated/…。不同之处在于您的比较测试值是否在元素方面相同。 .base 告诉您数据的所有权。
    • @JoshAdel:谢谢,知道这很有用。
    【解决方案3】:

    这行得通吗:

    import numpy
    a = numpy.array([1, 2, 3, 4])
    b = numpy.ones((1000, a.shape[0]))
    b *= a
    b = b.flatten()
    

    【讨论】:

    • 如果您要制作副本,这似乎是一种非常昂贵的做事方式,并且比仅使用 np.tile 慢约 15 倍
    【解决方案4】:

    我并不是说这是最优雅的解决方案,因为您必须欺骗 numpy 来创建对象数组(请参阅注释行)

    from numpy import array
    
    n = 3
    
    a = array([1,2])
    a.setflags(write=False)
    t = [a]*n + [array([1])] # Append spurious array that is not len(a)
    r = array(t,dtype=object)
    r.setflags(write=False)
    
    assert id(a) == id(t[1]) == id(r[1])
    

    【讨论】:

      【解决方案5】:

      我不是 100% 确定您所说的“不复制数据 1000 次”是什么意思。如果您正在寻找一种 numpy 方法来一举从a 构建b(而不是循环),您可以使用:

      a = np.arange(1000)
      b = np.tile(a,1000)
      

      否则,我会这样做:

      a = np.arange(1000)
      ii = [700,2000,10000] # The indices you want of the tiled array
      b = a[np.mod(ii,a.size)]
      

      b 在这种情况下不是 a 的视图,因为它有花哨的索引(它会复制),但至少它返回一个 numpy 数组并且不会在内存中创建 1000*1000x1 数组并且只包含你想要的元素。

      只要它们是不可变的(请参阅Immutable numpy array?),您需要为每个单独切换标志,因为副本不保留标志设置。

      【讨论】:

        猜你喜欢
        • 2014-07-04
        • 2015-07-12
        • 2011-12-13
        • 2020-09-29
        • 2016-08-19
        • 2013-04-10
        • 1970-01-01
        相关资源
        最近更新 更多