简体   繁体   English

python 中 3D 数据数组中缺失值的插值

[英]Interpolation of missing values in 3D data-array in python

I am struggeling with the following issue for quite some time and could not find a working solution yet.我在以下问题上苦苦挣扎了很长一段时间,但还没有找到可行的解决方案。

I want to interpolate missing values (nan) in my data-array [in Python].我想在我的数据数组 [in Python] 中插入缺失值 (nan)。 The array has the dimension lon, lat, time – it is a raster dataset over time.该数组的维度为 lon、lat、time——它是一个随时间变化的栅格数据集。

Unfortunately there are some timesteps where all values are missing and where an interpolation with lon and lat (2D) is not possible.不幸的是,在某些时间步长中所有值都丢失了,并且无法使用 lon 和 lat (2D) 进行插值。 This is why I came up with the idea to interpolate over the time axis.这就是为什么我想出在时间轴上插值的想法。 I want the missing value of one timesteps gets interpolated with the value of the timestep before and after at the exact same pixel.我希望一个时间步的缺失值在完全相同的像素处与之前和之后的时间步的值进行插值。

Do you have any ideas how to do that?你有什么想法吗?

My current attempt was:我目前的尝试是:

LAI_data LAI_data

" def arr_interp(array): arrN=np.array(array,copy=False) arrN[np.isnan(arrN)]=interpolate.interp2d(LAI.lat, LAI.lon, LAI.time, fill_value="nan") " def arr_interp(array): arrN=np.array(array,copy=False) arrN[np.isnan(arrN)]=interpolate.interp2d(LAI.lat, LAI.lon, LAI.time, fill_value="nan" )

arr_interp(LAI)" arr_interp(LAI)"

The problem is that the NaN data may form blocks, where you cannot interpolate from the neighbors.问题是 NaN 数据可能会形成块,您无法从邻居中插值。

A solution is to do Gauss Seidel interpolation solving the Laplace equation , (which creates data minimizing the curvature of the function).一种解决方案是进行高斯塞德尔插值求解拉普拉斯方程,(它创建的数据使函数的曲率最小化)。

This code finds the NaN values and does a 3D interpolation.此代码查找 NaN 值并执行 3D 插值。 I do not have access to your data, so it is done over synthetic data.我无权访问您的数据,因此它是通过合成数据完成的。

import numpy as np
import matplotlib.pyplot as plt


# create data
print("Creating data...")
size = 10  # 3D matrix of size: size³
# create x,y,z grid
x, y, z = np.meshgrid(np.arange(0, size), np.arange(
    0, size), np.arange(0, size))


def f(x, y, z):
    """function to create synthetic data"""
    return np.sin((x+y+z)/2)


data = np.zeros((size, size, size))
data[x, y, z] = f(x, y, z)

# create corrupted data
sizeCorruptedData = int(data.size*.2)  # 20% of data is corrupted
# create random x,y,z index for NaN values
xc, yc, zc = np.random.randint(0, size, (3, sizeCorruptedData))

corruptedData = data.copy()
corruptedData[xc, yc, zc] = np.nan

# Interpolate on NaN values
print("Interpolating...")

# get index of nan in corrupted data
nanIndex = np.isnan(corruptedData).nonzero()

interpolatedData = data.copy()
# make an initial guess for the interpolated data using the mean of the non NaN values
interpolatedData[nanIndex] = np.nanmean(corruptedData)


def sign(x):
    """returns the sign of the neighbor to be averaged for boundary elements"""
    if x == 0:
        return [1, 1]
    elif x == size-1:
        return [-1, -1]
    else:
        return [-1, 1]

#calculate kernels for the averages on boundaries/non boundary elements
for i in range(len(nanIndex)):
    nanIndex = *nanIndex, np.array([sign(x) for x in nanIndex[i]])

# gauss seidel iteration to interpolate Nan values with neighbors
# https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method
for _ in range(100):
    for x, y, z, dx, dy, dz in zip(*nanIndex):
        interpolatedData[x, y, z] = (
            (interpolatedData[x+dx[0], y, z] + interpolatedData[x+dx[1], y, z] +
             interpolatedData[x, y+dy[0], z] + interpolatedData[x, y+dy[1], z] +
             interpolatedData[x, y, z+dz[0]] + interpolatedData[x, y, z+dz[1]]) / 6)


# plot results
f, axarr = plt.subplots(2, 2)
axarr[0, 0].imshow(data[:, :, 1])
axarr[0, 0].title.set_text('Original Data')
axarr[0, 1].imshow(corruptedData[:, :, 1])
axarr[0, 1].title.set_text('Corrupted Data')
axarr[1, 0].imshow(interpolatedData[:, :, 1])
axarr[1, 0].title.set_text('Fixed Data')
axarr[1, 1].imshow(data[:, :, 1]-interpolatedData[:, :, 1])
axarr[1, 1].title.set_text('Error = Original-Fixed')
f.tight_layout()
plt.show()

在此处输入图像描述

That helped me a lot - thanks!!!这对我帮助很大-谢谢!!!

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

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