Python 数组处理:如何逐像素生成新值

1 投票
1 回答
1165 浏览
提问于 2025-04-18 07:36

我遇到的问题是关于在Python中处理数组的。我想做的是分析一个多波段的栅格图,并根据分析结果输出另一个栅格图。

举个实际的例子:我有一个包含3个波段的栅格图,我想查看同一个像素在不同波段的值是递增还是递减(从波段1到波段3)。如果这些值是递增的,我会给这个像素在新的输出栅格图中赋值为“1”(或者也可以是同一个栅格图中的新波段)。如果值是递减的,我会赋值为“2”。我已经定义了函数并读取了数组的值,但我在为每个像素递归构建列表并为新的栅格图赋值时遇到了困难。

我现在的代码如下:

import arcpy
import numpy as np

arcpy.env.workspace = r"\\workspace"

def decrease(A):
    return all(A[i] >= A[i+1] for i in range(len(A)-1)) # function to check if a list has decreasing values
def increase(A):
    return all(A[i] <= A[i+1] for i in range(len(A)-1))  # function to check if a list has increasing values
def no0(A,val):
    return[value for value in A if value !=val]   # function to check if a list has 0 values, and if so, strip them

myArray = arcpy.RasterToNumpyArray(r"raster_3bands.img")  # my 3 bands raster

print myArray.shape  # to see how many dimensions the array has
for z in range(3): # where z is the number of bands, in my case 3
    for y in range(6): #the number of columns, i.e. the vertical axis, in my case 6
        for x in range(6): #the number of rows,i.e. the horizontal axis, in my case 6.
            a = myArray[z,y,x] # get all the values for the 3 bands
            print "The value for axes:  ", z,y,x, " is: ",a

我缺少的部分是: 1. 如何为每个像素构建一个列表,用来存储三个对应的波段值,这样我就可以在这些列表上运行递减和递增的函数。 2. 如何逐个像素地赋值,并将这个数组存储为新的栅格图。

非常感谢你耐心阅读这些内容,

Bogdan

下面是处理3个波段栅格图的代码:

import arcpy, os
import numpy as np
myArray = arcpy.RasterToNumPyArray(r"\\nas2\home\bpalade\Downloads\test.img")
nbands = 3

print "Array dimensions are: ", myArray.shape
print "\n"
print "The array is: "
print "\n"
print myArray


increasing_pixels = np.product([(myArray[i] <= myArray[i+1]) for i in range(nbands-1)],axis=0)
decreasing_pixels = np.product([(myArray[i] >= myArray[i+1]) for i in range(nbands-1)],axis=0)

new_band = np.zeros_like(myArray[0])

new_band[increasing_pixels] = 1
new_band[decreasing_pixels] = 2

print "\n"
print "The new array is: "
print "\n"
print new_band

结果以jpeg格式附上

我没有看到jpeg,所以我从我的结果窗口复制/粘贴:

Array dimensions are:  (3L, 4L, 4L)


The array is: 


[[[60 62 62 60]
  [64 64 63 60]
  [62 62 58 55]
  [59 57 54 50]]

 [[53 55 55 55]
  [57 57 56 55]
  [55 55 51 50]
  [52 50 47 45]]

 [[35 37 37 36]
  [39 39 38 36]
  [37 37 33 31]
  [34 32 29 26]]]


The new array is: 


[[1 1 1 1]
 [2 2 2 2]
 [0 0 0 0]
 [0 0 0 0]]
>>> 

1 个回答

0

首先要考虑的是代码的结构。当使用numpy时(尤其是在这种情况下),通常不需要使用循环。你可以简单地沿着轴进行向量化操作。

在这个例子中,你可以使用数组广播来找出哪些像素组是在增加或减少的。

increasing_pixels = (myArray[0] <= myArray[1]) * (myArray[1] <= myArray[2])

这样你会得到一个布尔数组,其中 True 的像素表示在三个波段中是增加的。减少的像素也可以用同样的方法找到(这次 True 表示在波段中是减少的像素):

decreasing_pixels = (myArray[0] >= myArray[1]) * (myArray[1] >= myArray[2])

这些数组可以作为你的栅格的掩码,帮助你识别出想要改变值的像素。下面是一个基于原始三个波段中像素增加或减少值创建新波段的例子。

new_band = np.zeros_like(myArray[0])

new_band[increasing_pixels==True] = 1
new_band[decreasing_pixels==True] = 2

编辑:

对于任意数量的波段,上面的比较可以用以下方式替代:

increasing_pixels = np.product([(myArray[i] <= myArray[i+1]) for i in range(nbands-1)],axis=0)
decreasing_pixels = np.product([(myArray[i] >= myArray[i+1]) for i in range(nbands-1)],axis=0)

撰写回答