更新2array中具有给定值且相邻值为平均值的所有元素



考虑一个2array数字数组,其中一个特定的值,即0,表示"无数据"。在某些情况下,可能需要用邻近单元格的值更新这些no data值。例如,我有两个网格,一个是包裹id,另一个是到主要城市的运输时间。有些id将只与没有数据传输时间单元重叠。在这里,使用相邻网格单元格的平均值实际上是一个不错的猜测。但是,更关注抽象的问题,考虑以下设置

v_shp_ids = np.array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]])
v_shp_ids = v_shp_ids.ravel()
raster = np.array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 0]])
raster_r = raster.ravel()
zs = pd.concat([pd.Series(v_shp_ids), pd.Series(raster_r)], axis=1)

这里,v_shp_ids表示包裹ID 1由所有单元格表示。栅格是说只有一个单元格有一个值。我想让栅格充满1。(从一个简单的例子开始)。

这是我的解决方案

# Dictionary to store no data updates
na_update = {}
# Num rows in raster 2darray
i_end = len(raster)
# Num cols in raster 2darray
j_end = len(raster[0])
# Hard coding nodata = 0 for the example arrays I input above
nodata = 0
# Number of raster cells with no data
fill_length = len(zs.loc[zs[1] == nodata])
# Copy the dataframe for no data raster cells only
zs_na = zs.loc[zs[1] == nodata].copy()
# While the updated data dictionary is not full, loop
while len(na_update) != fill_length:
# For each 1darray index in the df
for ind, row in zs_na.iterrows():
# get the corresponding raster grid cell
i = ind // j_end
j = ind % j_end
# get the slice of neighboring pixel cells and flatten
neighb = raster[max(i-1,0):min(i+2,i_end),
max(j-1,0):min(j+2,j_end)].flatten()
# get the average of these neighboring, excluding na values
neighb_avg = np.ma.masked_values(neighb, nodata).mean()
# store average in dictionary if we can and update the pixels
if neighb_avg is not np.ma.masked:
na_update[ind] = neighb_avg.astype(raster_r.dtype)
raster[i, j] = na_update[ind]
# update the df to the remaining pixels with na remaining
zs_na = zs_na[~zs_na.index.isin(na_update.keys())]

我知道卷积可能是这里的一种方法,但我的一些担忧是a)我不想计算每个单元格的最近邻平均值,因为在许多情况下,我不处理没有数据单元格b)我不能事先告诉邻居大小,以确保所有的数据单元得到一个值,并确保他们都这样做,邻居可能太大,继续作为一个合理的近似值(当然,你可能会认为整个方法不是一个合理的近似值)

我有两个主要问题

  1. 是否有一种方法可以在数据框(甚至栅格)上使用索引来做同样的事情?我尝试过各种z。loc[zs[1] == nodata, 1] = #尝试取栅格中相邻元素的平均值

  2. 我完全错过了一个合理的方法填充没有数据单元格吗?

我发现这是一个有趣的问题,我非常期待想法/讨论。

下面是一个很棒的栅格函数:https://rasterio.readthedocs.io/en/latest/api/rasterio.fill.html

函数是从栅格中填充数据。填充模块。来自描述:

通过插值填充栅格数据

该算法将为所有指定的nodata插入值像素(在掩码中以零标记)。每个像素有四个方向进行二次搜索是为了找到要插值的值(使用inverse)距离加权)。一旦所有的值都被插值,0或更多平滑迭代(插值像素上的3x3平均滤波器)是用于平滑伪影。

函数调用是

rasterio.fill.fillnodata(image, mask=None, max_search_distance=100.0, smoothing_iterations=0)

我传入了

rasterio.fill.fillnodata(image = np.ma.masked_array(raster, nodata))

最新更新