为什么这个numpy数组操作这么慢?

时间:2011-04-06 13:54:51

标签: python arrays matrix numpy

我是一个python初学者,我试图平均两个NumPy 2D阵列的形状为(1024,1024)。这样做很快:

newImage = (image1 + image2) / 2

但是现在图像有一个“掩码”,如果设置为零,它会使某些元素无效。这意味着如果其中一个元素为零,则结果元素也应为零。我的琐碎解决方案是:

newImage = numpy.zeros( (1024,1024) , dtype=numpy.int16 )

for y in xrange(newImage.shape[0]):
   for x in xrange(newImage.shape[1]):
      val1 = image1[y][x]  
      val2 = image2[y][x]                            
      if val1!=0 and val2!=0:               
         newImage[y][x] = (val1 + val2) / 2

但这真的很慢。我没有时间,但它似乎慢了100倍。

我也尝试使用lambda运算符和“map”,但这不会返回NumPy数组。

4 个答案:

答案 0 :(得分:8)

试试这个:

newImage = numpy.where(np.logical_and(image1, image2), (image1 + image2) / 2, 0)

image1image2都不等于零,取其均值,否则为零。

答案 1 :(得分:2)

使用本机Python代码循环通常比使用它慢得多 使用快速C循环的内置工具。我不熟悉NumPy;能够 您使用map()从两个输入数组转换为 输出?如果是这样,那应该更快。

答案 2 :(得分:1)

显式for循环在Python中效率非常低,不仅适用于numpy操作。幸运的是,有更快的方法来解决我们的问题。如果内存不是问题,这个解决方案非常好:

import numpy as np
new_image = np.zeros((1024, 1024), dtype=np.int16)
valid = (image1!=0) & (image2!=0)
new_image[valid] = (image1+image2)[valid]

使用蒙版数组的另一种解决方案,它不会创建数组的副本(它们代表原始image1/2的视图:

m1 = np.ma.masked_equal(image1, 0)
m2 = np.ma.masked_equal(image2, 0)
new_image = (m1+m2).filled(0)

更新:对于大约有1000个非零条目的数组,第一个解决方案似乎比第二个解决方案快3倍。

答案 3 :(得分:0)

numpy数组访问操作似乎很慢。我看不出任何理由。您可以通过构建一个简单的示例来清楚地看到它:

    import numpy
    # numpy version
    def at(s,n):
      t1=time.time()
      a=numpy.zeros(s,dtype=numpy.int32)
      for i in range(n):
        a[i%s]=n
      t2=time.time()
      return t2-t1
    # native version
    def an(s,n):
      t1=time.time()
      a=[(i) for i in range(s)]
      for i in range(n):
        a[i%s]=n
      t2=time.time()
      return t2-t1

    # test
    [at(100000,1000000),an(100000,1000000)]

结果:[0.21972250938415527,0.15950298309326172]