代码之家  ›  专栏  ›  技术社区  ›  ZisIsNotZis

Numpy将非连续数组的连续部分视为较大的数据类型

  •  2
  • ZisIsNotZis  · 技术社区  · 7 年前

    # data is actually load from a source file
    a = np.random.randint(0, 256, 2**28, 'B').view('c')
    

    由于复制效率不高(并且会产生缓存丢失等问题),因此我使用跨步技巧直接生成了三元图:

    tri = np.lib.stride_tricks.as_strided(a, (len(a)-2,3), a.strides*2)
    

    这将生成一个具有形状的三角图列表 (2**28-2, 3) S3 )因此,numpy更“合理”地显示它(而不是单个字符)。

    tri = tri.view('S3')
    

    它给出了例外情况:

    ValueError: To change to a dtype of a different size, the array must be C-contiguous
    

    我知道为了创建一个有意义的视图,通常数据应该是连续的,但是这个数据在“应该在哪里”是连续的:每三个元素都是连续的。

    所以我想知道 如何 view 非连续中的连续部分 np.ndarray ? 一个更“标准”的方式会更好,而黑客的方式也是受欢迎的。看来我能定下来 shape stride np.lib.stride_tricks.as_strided ,但我不能强迫你 dtype 这就是问题所在。

    编辑

    非连续数组可以通过简单的切片生成。例如:

    np.empty((8, 4), 'uint32')[:, :2].view('uint64')
    

    将抛出上面相同的异常(而从内存的角度来看,我应该能够做到这一点)。这种情况比我上面的例子更常见。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Paul Panzer    7 年前

    如果您可以访问从中派生非连续数组的连续数组,则通常可以绕过此限制。

    例如,您的三角形可以如下获得:

    >>> a = np.random.randint(0, 256, 2**28, 'B').view('c')
    >>> a
    array([b')', b'\xf2', b'\xf7', ..., b'\xf4', b'\xf1', b'z'], dtype='|S1')
    >>> np.lib.stride_tricks.as_strided(a[:0].view('S3'), ((2**28)-2,), (1,))
    array([b')\xf2\xf7', b'\xf2\xf7\x14', b'\xf7\x14\x1b', ...,
           b'\xc9\x14\xf4', b'\x14\xf4\xf1', b'\xf4\xf1z'], dtype='|S3')
    

    as_strided 不做很多检查,我们基本上可以随心所欲。

    似乎我们总是可以通过切片到大小为0的数组来获得这样的存根。第二个例子是:

    >>> X = np.empty((8, 4), 'uint32')[:, :2]
    >>> np.lib.stride_tricks.as_strided(X[:0].view(np.uint64), (8, 1), X.strides)
    array([[140133325248280],
           [             32],
           [       32083728],
           [       31978800],
           [              0],
           [       29686448],
           [             32],
           [       32362720]], dtype=uint64)