Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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数组转换为C-连续顺序的最便宜方法?_Python_Arrays_Numpy - Fatal编程技术网

Python 将numpy数组转换为C-连续顺序的最便宜方法?

Python 将numpy数组转换为C-连续顺序的最便宜方法?,python,arrays,numpy,Python,Arrays,Numpy,下面生成一个C-连续numpy数组: import numpy a = numpy.ones((1024,1024,5)) 现在,如果我将其切片,结果可能不再相同。例如: bn = a[:, :, n] 从0到4使用n。 我的问题是我需要bn是C-连续的,我需要对a的许多实例这样做。我只需要每个bn一次,并且希望避免这样做 bn = bn.copy(order='C') 我也不想重写我的代码 a = numpy.ones((5,1024,1024)) 有没有比拷贝更快、更便宜的方式获

下面生成一个C-连续numpy数组:

import numpy

a = numpy.ones((1024,1024,5))
现在,如果我将其切片,结果可能不再相同。例如:

bn = a[:, :, n]
从0到4使用
n
。 我的问题是我需要
bn
是C-连续的,我需要对a的许多实例这样做。我只需要每个
bn
一次,并且希望避免这样做

bn  = bn.copy(order='C')
我也不想重写我的代码

a = numpy.ones((5,1024,1024))
有没有比拷贝更快、更便宜的方式获得
bn

背景:

我想使用

import hashlib

hashlib.sha1(a[:, :, n]).hexdigest()

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

要强制numpy数组
x
为C-连续,而不在开始时进行不必要的复制,应该使用

 x = numpy.asarray(x, order='C')
请注意,如果此数组不是C-连续的,则在效率方面可能与
x.copy(order='C')
类似。我认为没有办法解决这个问题。除非将数据复制到新位置,否则无法重新组织内存中数组的对齐方式


重写代码,使其首先使用切片索引,如
numpy.ones((510241024))
似乎是唯一合理的优化方法

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

x=numpy.ascontiguousarray(x)

这是正确的处理方法

如果需要fortran命令,请使用

如前所述,如有必要,该功能将进行复制。所以这是没有办法的。您可以在操作前进行尝试,使短轴成为第一个轴。这将为您提供阵列的视图

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

所以rollaxis也不能解决这个问题。

目前的情况是,任何将切片
bn
强制为C连续顺序的尝试都会创建一个副本

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

>>> a = numpy.ones((1024, 1024, 5), order='f')
然后,切片也是F-连续的:

>>> bn = a[:, :, 0]
>>> bn.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : False
  ...
这意味着切片
bn
的转置将是C顺序,并且转置不会创建副本:

>>> bn.T.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  ...
然后可以对切片进行散列:

>>> hashlib.sha1(bn.T).hexdigest()
'01dfa447dafe16b9a2972ce05c79410e6a96840e'

另一方面,我只是通过大量调试了解了hashlib的行为,直到我发现异常的真正来源。python文档不应该提到这一点吗?在我看来,这似乎是解决方案的正确路径,但在转换视图时,您正在更改其他两个轴的顺序,这并不好。类似于
a=numpy.ones((5,1024,1024)).transpose(1,2,0)
的东西为您提供了一个既不是C也不是Fortran连续的数组,但当沿着最后一个维度进行索引时,它会生成C连续的切片。我怎么知道“它已经是这样开始的”呢?如果是的话,我就不会犯错误吗?我的案例是使用
.values
从pandas中获取一个列。为什么它会或不会是C连续的?例如,您创建了一个2D numpy数组(默认情况下是C顺序的),您将其转置,然后它将是F顺序的。因此,这取决于对阵列执行的操作。使用pandas,块管理器可以在任何情况下使用
x.flags
进行检查。