在python中操作数组

时间:2014-07-12 14:09:33

标签: python arrays numpy

我有一个通过阅读图像获得的numpy数组。

data=band.ReadAsArray(0,0,rows,cols)

现在的问题是,使用循环来操作数据大约需要13分钟。我怎么能减少这个时间。有没有其他解决方案。

示例代码

for i in range(rows):
     for j in range(cols):
          if data[i][j]>1 and data[i][j]<30:
                 data[i][j]=255
          elif data[i][j]<1:
                  data[i][j]=0
          else:
              data[i][j]=1

需要太长时间。任何简短的方法

2 个答案:

答案 0 :(得分:3)

使用numpy,您可以使用遮罩选择具有特定条件的所有元素,如下面的代码示例所示:

import numpy as np

a = np.random.random((5,5))
a[a<0.5] = 0.0

print(a)
# [[ 0.          0.94925686  0.8946333   0.51562938  0.99873065]
#  [ 0.          0.          0.          0.          0.        ]
#  [ 0.86719795  0.          0.8187514   0.          0.72529116]
#  [ 0.6036299   0.9463493   0.78283466  0.6516331   0.84991734]
#  [ 0.72939806  0.85408697  0.          0.59062025  0.6704499 ]]

如果您希望重新编写代码,那么它可能类似于:

data=band.ReadAsArray(0,0,rows,cols)
data[data >= 1 & data<30] = 255
data[data<1] = 0

答案 1 :(得分:3)

您可以使用布尔数组来指定您有兴趣更改的值,而不是循环。例如,如果我们有一个数组

>>> a = np.array([[0.1, 0.5, 1], [10, 20, 30], [40, 50, 60]])
>>> a
array([[  0.1,   0.5,   1. ],
       [ 10. ,  20. ,  30. ],
       [ 40. ,  50. ,  60. ]])

我们可以将您的逻辑应用于

>>> anew = np.empty_like(a)
>>> anew.fill(1)
>>> anew[a < 1] = 0
>>> anew[(a > 1) & (a < 30)] = 255
>>> anew
array([[   0.,    0.,    1.],
       [ 255.,  255.,    1.],
       [   1.,    1.,    1.]])

这是因为numpy索引的工作原理:

>>> a < 1
array([[ True,  True, False],
       [False, False, False],
       [False, False, False]], dtype=bool)
>>> anew[a < 1]
array([ 0.,  0.])

注意:我们并不真正需要anew - 您可以对a本身采取行动 - 但是您必须小心处理您应用的订单,以防您的条件和目标值重叠。

注意#2:你的条件意味着如果数组中的元素正好是30或更大,它将变为1,而不是255.这似乎有点奇怪,但它&#39 ; s你的代码做了什么,所以我复制了它。