最简单的方法是将numpy数组变成C连续的顺序?

Dan*_* Sk 8 python arrays numpy

以下产生一个C连续的numpy数组:

import numpy

a = numpy.ones((1024,1024,5))
Run Code Online (Sandbox Code Playgroud)

现在,如果我切片,结果可能不再相同.例如:

bn = a[:, :, n]
Run Code Online (Sandbox Code Playgroud)

n从0到4我的问题是,我需要bn为C连续的,我需要为的许多情况下做到这一点.我只需要每bn一次,并希望避免这样做

bn  = bn.copy(order='C')
Run Code Online (Sandbox Code Playgroud)

我也不想重写我的代码

a = numpy.ones((5,1024,1024))
Run Code Online (Sandbox Code Playgroud)

有没有bn比复制更快,更便宜的方式?

背景:

我希望a使用每个切片

import hashlib

hashlib.sha1(a[:, :, n]).hexdigest()
Run Code Online (Sandbox Code Playgroud)

不幸的是,这将抛出一个ValueError抱怨订单.所以,如果有另一种快速获取我想要的哈希的方法,我也会使用它.

rth*_*rth 6

要强制一个numpy数组x为C-contiguous,而不是在它已经是那种方式开始时制作不必要的副本,你应该使用,

 x = numpy.asarray(x, order='C')
Run Code Online (Sandbox Code Playgroud)

注意,如果这个数组不是C连续的,那么在效率方面它可能是相似的x.copy(order='C').我认为没有办法绕过它.除了将数据副本复制到新位置之外,您无法重新组织数组在内存中的对齐方式.

重写你的代码,使它首先使用切片索引,因为这numpy.ones((5,1024,1024))似乎是优化它的唯一合理方法.


Bor*_*ort 6

这是numpy与C接口时的标准操作.看看numpy.ascontiguousarray

x=numpy.ascontiguousarray(x)

是处理它的正确方法.

如果你需要fortran命令,请使用numpy.asfortranarray.

如上所述,该功能将在必要时复制.所以没有办法绕过它.您可以尝试rollaxis你的操作之前,使得短轴是第一轴线.这为您提供了数组视图

In [2]: A=np.random.rand(1024,1024,5)
In [3]: B=np.rollaxis(A,2)
In [4]: B.shape
Out[4]: (5, 1024, 1024)
In [5]: B.flags
Out[5]:
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

In [6]: A.flags
Out[6]:
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
Run Code Online (Sandbox Code Playgroud)

因此,rollaxis也没有解决这个问题.


Ale*_*ley 5

就目前而言,将切片强制转换bn为C连续顺序的任何尝试都将创建一个副本。

如果您不想更改开始时使用的形状(并且不需要a以C顺序本身),则一种可能的解决方案是以aFortran顺序从数组开始:

>>> a = numpy.ones((1024, 1024, 5), order='f')
Run Code Online (Sandbox Code Playgroud)

切片也随后是F连续的:

>>> bn = a[:, :, 0]
>>> bn.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : False
  ...
Run Code Online (Sandbox Code Playgroud)

这意味着片的转置bn将在C秩序和换位并没有创建一个副本:

>>> bn.T.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  ...
Run Code Online (Sandbox Code Playgroud)

然后,您可以对切片进行哈希处理:

>>> hashlib.sha1(bn.T).hexdigest()
'01dfa447dafe16b9a2972ce05c79410e6a96840e'
Run Code Online (Sandbox Code Playgroud)

  • 在我看来,这似乎是解决方案的正确路径,但是在移置视图时,您正在更改其他两个轴的顺序,这不是很好。像`a = numpy.ones((5,1024,1024))。transpose(1、2、0)这样的东西会给你一个既不是C也不是Fortran连续的数组,但是当沿着数组索引时会产生C连续的切片。最后一个维度。 (3认同)