您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

python – Numpy大步招数抱怨“数组太大”,为什么?

5b51 2022/1/14 8:20:21 python 字数 3780 阅读 471 来源 www.jb51.cc/python

在numpy(1.8)中,我想将这个计算从 Python循环中转移到更多numpy-ish以获得更好的性能: (width, height) = base.shape (toolw, toolh) = tool.shape for i in range(0, width-toolw): for j in range(0, height-toolh): zdiff[i,j]

概述

(width,height) = base.shape
(toolw,toolh) = tool.shape
for i in range(0,width-toolw):
    for j in range(0,height-toolh):
        zdiff[i,j] = (tool - base[i:i+toolw,j:j+toolh]).min()

base是一个~2000×2000阵列,工具是25×25阵列. (背景背景:基础和工具是高度图,我试图找出最接近基础的工具移动方法.)

我试图使用一个跨越式的技巧,从这开始:

base_view = np.lib.stride_tricks.as_strided(base,shape=(2000,2000,25,25),strides=(base.strides * 2))

这将使base_view [10,20]成为25×25的值,从(10,20)左上角的基数开始.

然而,这与“阵列太大”失败了.从价值测试来看,当数组的潜在大小(例如2000 * 2000 * 25 * 25 * 8)超过2 ^ 32-ish并且它触发溢出检查时,它会报告此问题,该溢出检查将所有维度相乘. (我使用的是32位Python安装).

我觉得我错过了一些东西 – 为什么当步幅值明显起作用时,它不会让我创造这种“跨步观点”?有没有办法强迫这个?

更一般地说,有没有办法优化我的循环?

更新:确切错误

ValueError                                Traceback (most recent call last)
<ipython-input-14-313b3d6c74fa> in <module>()
----> 1 newa = np.lib.stride_tricks.as_strided(base,shape=(1000,1000,strides=(base.strides * 2))

C:\Python27\lib\site-packages\numpy\lib\stride_tricks.pyc in as_strided(x,shape,strides)
     28     if strides is not None:
     29         interface['strides'] = tuple(strides)
---> 30     array = np.asarray(DummyArray(interface,base=x))
     31     # Make sure dtype is correct in case of custom dtype
     32     array.dtype = x.dtype

C:\Python27\lib\site-packages\numpy\core\numeric.pyc in asarray(a,dtype,order)
    458 
    459     """
--> 460     return array(a,copy=False,order=order)
    461 
    462 def asanyarray(a,dtype=None,order=None):

ValueError: array is too big.

请注意,在您的原始代码中,我更改了范围并切换了宽度和高度,因为我认为这是您的意图..

import numpy as np

height,width = 500,500
toolh,toolw = 6,6

base = np.random.rand(height,width)
tool = np.random.rand(toolh,toolw)

m,n = height-toolh+1,width-toolw+1

def height_diff_old(base,tool):
    zdiff = np.empty((m,n))
    for i in range(m):
        for j in range(n):
            zdiff[i,j] = (tool - base[i:i+toolh,j:j+toolw]).min()
    return zdiff

def height_diff_new(base,n))
    zdiff.fill(np.inf)
    for i in range(toolh):
        for j in range(toolw):
            diff_ij = tool[i,j] - base[i:i+m,j:j+n]
            np.minimum(zdiff,diff_ij,out=zdiff)
    return zdiff

当然,你想要计算实际函数中的高度和宽度,但是对于测试来说,将它们作为全局变量更容易.

对于给定的数组大小,原始代码在7.38秒内运行,而新代码在我的系统上仅需206毫秒.我假设新代码对于你的数组大小也更快,但我不确定它的扩展程度如何:)

您可能感兴趣或可能不感兴趣的其他替代方案是使用Numba或Cython,在许多情况下,它应该比您想到的任何“矢量化”numpy代码更快.

总结

以上是编程之家为你收集整理的python – Numpy大步招数抱怨“数组太大”,为什么?全部内容,希望文章能够帮你解决python – Numpy大步招数抱怨“数组太大”,为什么?所遇到的程序开发问题。


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶