简体   繁体   English

使用python,numpy重新分类栅格值

[英]Reclassify raster values using python, numpy

I have a raster which contains the values [0, 1, 2, 3, 4, 255] and I want to reclassify it. 我有一个包含值[0、1、2、3、4、255]的栅格,我想对其重新分类。 It worked fine doing it pixel by pixel but that took forever, so I tried to change it... : 逐个像素地进行工作效果很好,但是花了很多时间,所以我尝试更改它...:

# working
for j in range(cf.RasterXSize):
    for i in range(cf.RasterYSize):
        if cf_array[i, j] <= 1:
            cf_array[i, j] = 5  # 5 = No Clouds
        elif 1 < cf_array[i, j] <= 4:
            cf_array[i, j] = 6  # 6 = Clouds
        elif 4 < cf_array[i, j]:
            cf_array[i, j] = 7  # 7 = NoData

# Not working:
cf_array[np.where(cf_array <= 1)] = 5
cf_array[np.where((1 < cf_array) & (cf_array <= 4))] = 6
cf_array[np.where(cf_array > 4)] = 7

values = list(numpy.unique(cf_array))
print (values)

And this is what I get when I print the value list with list(numpy.unique(cf_array)) : 这就是我使用list(numpy.unique(cf_array))打印值列表时得到的结果:
original raster: [0, 1, 2, 3, 4, 255] 原始栅格:[0、1、2、3、4、255]
after reclassify attempt: [7] 重新分类尝试后:[7]

So, why is that not working? 那么,为什么这不起作用? I found several existing threads regarding the reclassification of a raster but all suggested the numpy.where method which is apparently not working for me... 我发现了一些有关栅格重分类的现有线程,但是都建议使用numpy.where方法,该方法显然对我不起作用...

As has been noted, you don't need the where , however, I believe the issue is the order of your statements. 如前所述,您不需要where ,但是,我认为问题在于您的陈述顺序 You are first setting some elements to five and six, respectively, and then finally everything bigger than four to seven - this will include all those elements previously set to five and six. 首先,将一些元素分别设置为5和6,然后将所有大于4的元素设置为7-这将包括先前设置为5和6的所有元素。 It should work by changing the order: 它应该通过更改顺序来工作:

cf_array[cf_array > 4] = 7
cf_array[cf_array <= 1] = 5
cf_array[(1 < cf_array) & (cf_array <= 4)] = 6

Perhaps worthwhile mentioning: Since the ordering makes such a difference here and can introduce subtle problems which can be difficult to find, a safer approach might be to first collect the indices and afterwards change the target array: 也许值得一提:由于排序在这里有很大的不同,并且可能会引入难以发现的细微问题,因此,更安全的方法可能是先收集索引,然后更改目标数组:

# collect index arrays
one_or_less = cf_array <= 1
from_2_to_4 = (1 < cf_array) & (cf_array <= 4)
greater_4 = cf_array > 4

# now modify target array
cf_array[one_or_less] = 5
cf_array[from_2_to_4] = 6
cf_array[greater_4] = 7

You don't need numpy.where . 您不需要numpy.where Try: 尝试:

cf_array[cf_array <= 1] = 5
cf_array[(1 < cf_array) & (cf_array <= 4)] = 6
cf_array[cf_array > 4] = 7

You can simply use np.searchsorted for such a binning operation, like so - 您可以简单地将np.searchsorted用于此类装箱操作,如下所示-

np.searchsorted([1,4],cf_array)+5 # [1,4] act as the bin boundaries

Sample run - 样品运行-

In [55]: cf_array
Out[55]: 
array([[4, 4, 2, 5, 6],
       [0, 5, 5, 6, 0],
       [8, 3, 6, 1, 5],
       [6, 5, 8, 1, 2]])

In [56]: np.searchsorted([1,4],cf_array)+5
Out[56]: 
array([[6, 6, 6, 7, 7],
       [5, 7, 7, 7, 5],
       [7, 6, 7, 5, 7],
       [7, 7, 7, 5, 6]], dtype=int64)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM