使用for循环操作Numpy高程数组中的值

qojgxg4l  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(86)

我有一个高程阵列从.tif激光雷达表面。下面的数组示例。

Existing_example_array = [[ 0, 0, 1, 0, 0, 0, 0], 
                          [ 0, 1, 1, 1, 0, 0, 0], 
                          [ 0, 1, 1, 1, 1, 0, 0], 
                          [ 1, 1, 1, 1, 0, 0, 0], 
                          [ 0, 1, 1, 1, 1, 0, 0], 
                          [ 0, 1, 1, 0, 0, 0, 0]]

我的目标是使用下面的代码片段在一定的公差范围内填充表面,该代码片段将向任何>= 1的数字添加+1

geotiff_array = np.array(Existing_example_array)
sub_tif_array = geotiff_array[:]
sub_tif_array[sub_tif_array > 1] += 1

Fill = geotiff_array.tolist()
type(Fill)

得到以下高程阵列:

Filled_example_array = [[ 0, 0, 2, 0, 0, 0, 0], 
                        [ 0, 2, 2, 2, 0, 0, 0], 
                        [ 0, 2, 2, 2, 2, 0, 0], 
                        [ 2, 2, 2, 2, 0, 0, 0], 
                        [ 0, 2, 2, 2, 2, 0, 0], 
                        [ 0, 2, 2, 0, 0, 0, 0]]

然后,我使用下面的代码删除每个列表中的第一个和最后一个值:

for l in Fill:
    for i, x in enumerate(l):
        if x > 1:
            l[i] -= 100
            break
for l in Fill:
    for i, x in reversed([*enumerate(l)]):
        if x > 1:
            l[i] -= 100
            break

生成下面的高程数组:

Incorrect_example_array = [[ 0, 0, 0, 0, 0, 0, 0], 
                               [ 0, 1, 2, 1, 0, 0, 0], 
                               [ 0, 1, 2, 2, 1, 0, 0], 
                               [ 1, 2, 2, 1, 0, 0, 0], 
                               [ 0, 1, 2, 2, 1, 0, 0], 
                               [ 0, 1, 1, 0, 0, 0, 0]]

问题是第0行中的1被重复计算。我一直在解决这个问题,方法是手动添加额外的for loops,专门针对发生这种情况的某些行。有没有一种方法可以操作for循环,当一个数字在迭代中已经改变时,它会删除列表中的第一个和最后一个值并停止?或者告诉循环只在[1:-1]内工作,以生成下面正确的高程数组?

Correct_example_array = [[ 0, 0, 1, 0, 0, 0, 0], 
                             [ 0, 1, 2, 1, 0, 0, 0], 
                             [ 0, 1, 2, 2, 1, 0, 0], 
                             [ 1, 2, 2, 1, 0, 0, 0], 
                             [ 0, 1, 2, 2, 1, 0, 0], 
                             [ 0, 1, 1, 0, 0, 0, 0]]
o0lyfsai

o0lyfsai1#

不要循环。你想做的事情可以通过binary_erosion来实现:

from scipy.ndimage import binary_erosion

a = np.array([[ 0, 0, 1, 0, 0, 0, 0], 
              [ 0, 1, 1, 1, 0, 0, 0], 
              [ 0, 1, 1, 1, 1, 0, 0], 
              [ 1, 1, 1, 1, 0, 0, 0], 
              [ 0, 1, 1, 1, 1, 0, 0], 
              [ 0, 1, 1, 0, 0, 0, 0],
             ])

a[binary_erosion(a==1, structure=[[1,1,1]])] += 1

输出:

array([[0, 0, 1, 0, 0, 0, 0],
       [0, 1, 2, 1, 0, 0, 0],
       [0, 1, 2, 2, 1, 0, 0],
       [1, 2, 2, 1, 0, 0, 0],
       [0, 1, 2, 2, 1, 0, 0],
       [0, 1, 1, 0, 0, 0, 0]])
带迭代
from scipy.ndimage import binary_erosion

a = np.array([[ 0, 0, 1, 0, 0, 0, 0], 
              [ 0, 1, 1, 1, 0, 0, 0], 
              [ 0, 1, 1, 1, 1, 1, 0],
              [ 1, 1, 1, 1, 1, 1, 1],
              [ 1, 1, 1, 1, 0, 0, 0], 
              [ 0, 1, 1, 1, 1, 0, 0], 
              [ 0, 1, 1, 0, 0, 0, 0],
             ])

m = a>=1
while True:
    m = binary_erosion(m>=1, structure=[[1,1,1]])
    a += m
    if not m.max(): # if all False, stop
        break

视觉表示:

sbdsn5lh

sbdsn5lh2#

我不知道我是否错过了什么,但是如果我稍微修改一下你的代码,以便将1添加到sub_tif_array >= 1中的元素(注意相等),然后将1(而不是100)删除到第一个元素> 1,然后再次删除到最后一个元素> 1,我会得到正确的结果:

import numpy as np
Existing_example_array = [[0, 0, 1, 0, 0, 0, 0],
                          [0, 1, 1, 1, 0, 0, 0],
                          [0, 1, 1, 1, 1, 0, 0],
                          [1, 1, 1, 1, 0, 0, 0],
                          [0, 1, 1, 1, 1, 0, 0],
                          [0, 1, 1, 0, 0, 0, 0]]

geotiff_array = np.array(Existing_example_array)
sub_tif_array = geotiff_array[:]
sub_tif_array[sub_tif_array >= 1] += 1

Fill = sub_tif_array.tolist()

for l in Fill:
    for i, x in enumerate(l):
        if x > 1:
            l[i] -= 1
            break
for l in Fill:
    for i, x in reversed([*enumerate(l)]):
        if x > 1:
            l[i] -= 1
            break

结果:

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

相关问题