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抱怨订单.所以,如果有另一种快速获取我想要的哈希的方法,我也会使用它.
要强制一个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))似乎是优化它的唯一合理方法.
这是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也没有解决这个问题.
就目前而言,将切片强制转换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)