Interpolation des données de la grille Python au site Interpolation du voisin le plus proche Interpolation bilinéaire

interpolation du plus proche voisin

1. Importation de bibliothèque

import pandas as pd
import numpy as np
import netCDF4 as nc

2. Importation des données du site (le code peut être exécuté directement, et ceux qui veulent des données peuvent laisser un message)

#站点信息
stations_info = pd.read_excel('china_weather_stations.xlsx', 'Sheet1',
 index_col=None, na_values=['NA'])
 
lons = stations_info['经度'].to_numpy()
lats = stations_info['纬度'].to_numpy()

insérez la description de l'image ici


3. Importation de données de grille

#ERA5数据 
dataset = nc.Dataset("ERA5_single_level_2020_1-4-7-10.nc")

# 经纬度
longitude = dataset.variables['longitude'][:].data
latitude  = dataset.variables['latitude'][:].data
# 2m温度
t2m = dataset.variables['t2m'][2].data   # 2代表第二个数据,表示7月份的数据

insérez la description de l'image ici


4. Prétraitez la latitude et la longitude des données de la grille et modifiez la dimension de petite à grande (toutes les données n'ont pas besoin de cette étape)

Les latitudes ERA5 que nous utilisons vont de grandes à petites, ce qui n'est pas conforme aux habitudes d'utilisation. besoin de cette étape

latitude_old = latitude.copy()
t2m_old = t2m.copy()
nlats = len(latitude)
for i in range(nlats):
    latitude[i] = latitude_old[nlats-1-i]
    print(nlats-1-i, latitude_old[nlats-1-i])
    t2m[i,:] = t2m_old[nlats-1-i,:]

5. Filtrer les stations dans la plage de grille (pas obligatoire)

Filtrez les sites qui se trouvent uniquement dans la plage de points de grille, et nous n'interpolerons pas les sites qui ne se trouvent pas dans la plage de points de grille ;
此情况适用条件:站点数据范围比格点的数据范围大

# ERA5数据经纬度范围
lonMin = np.min(longitude)
lonMax = np.max(longitude)
latMin = np.min(latitude)
latMax = np.max(latitude)

#筛选范围内的气象站点
stations_info =  stations_info[stations_info["经度"] >= lonMin] 
stations_info =  stations_info[stations_info["经度"] <= lonMax] 
stations_info =  stations_info[stations_info["纬度"] >= latMin] 
stations_info =  stations_info[stations_info["纬度"] <= latMax] 

lonSta = stations_info['经度'].to_numpy()
latSta = stations_info['纬度'].to_numpy()

6. Effectuer le calcul d'interpolation

# 定义一个方法
def nearest_position(stn_lat, stn_lon, lat2d, lon2d):
    """获取最临近格点坐标索引
    stn_lat  : 站点纬度
    stn_lon  : 站点经度
    lat2d    : numpy.ndarray网格二维经度坐标
    lon2d    : numpy.ndarray网格二维纬度坐标
    Return: (y_index, x_index)
    """
    # 计算经纬度距离差(一个站点到每一个格点)
    difflat = stn_lat - lat2d
    difflon = stn_lon - lon2d
    # 计算欧氏距离
    rad = np.multiply(difflat,difflat)+np.multiply(difflon , difflon)
    # 找到距离最小的值的索引
    aa=np.where(rad==np.min(rad))
    ind=np.squeeze(np.array(aa)) # 维度压缩
    # 返回经纬度索引
    return tuple(ind)
t2m_sta_nearest = []

# 将一维的经纬度数据网格二维化
lon2D, lat2D = np.meshgrid(longitude, latitude)

# 利用循环对所有站点进行计算
for i in range(len(lonSta)):
    indexSta = nearest_position(latSta[i], lonSta[i], lat2D, lon2D)
    jSta = indexSta[0] # 范围结果的维度索引
    iSta = indexSta[1] # 范围结果的经度索引
    # 将每一步结果 t2m[jSta, iSta] 添加到列表中
    t2m_sta_nearest.append(t2m[jSta, iSta])
    
    
stations_info['t2m_nearest'] = np.array(t2m_sta_nearest)
# 重置索引(非必须)
stations_info.index = range(len(lonSta))
# 将数据保存为新的xlsx文件
stations_info.to_excel('weather_station_data.xlsx', sheet_name='Sheet1')

Interpolation bilinéaire : les points de grille Q12, Q22, Q11, Q21 sont connus, mais le point à interpoler est le point P, ce qui nécessite une interpolation bilinéaire. Tout d'abord, dans la direction de l'axe des x, deux paires de points R1 et R2 sont interpolées, ce est très simple, puis P points sont interpolés selon R1 et R2, c'est ce qu'on appelle l'interpolation bilinéaire. Mathématiquement, l'interpolation bilinéaire est une extension d'interpolation linéaire d'une fonction d'interpolation à deux variables, et son idée de base est d'effectuer une interpolation linéaire dans deux directions respectivement.

insérez la description de l'image ici

insérez la description de l'image ici








interpolation bilinéaire

1. Importation de bibliothèque

import pandas as pd
import numpy as np
import netCDF4 as nc

2. Importation des données du site (le code peut être exécuté directement, et ceux qui veulent des données peuvent laisser un message)

#站点信息
stations_info = pd.read_excel('china_weather_stations.xlsx', 'Sheet1',
 index_col=None, na_values=['NA'])
 
lons = stations_info['经度'].to_numpy()
lats = stations_info['纬度'].to_numpy()

insérez la description de l'image ici


3. Importation de données de grille

#ERA5数据 
dataset = nc.Dataset("ERA5_single_level_2020_1-4-7-10.nc")

# 经纬度
longitude = dataset.variables['longitude'][:].data
latitude  = dataset.variables['latitude'][:].data
# 2m温度
t2m = dataset.variables['t2m'][2].data   # 2代表第二个数据,表示7月份的数据

insérez la description de l'image ici


4. Prétraitement de la latitude et de la longitude des données de point de grille pour changer la dimension de petite à grande

Toutes les données ne nécessitent pas cette étape.
Les latitudes ERA5 que nous utilisons vont de grandes à petites, ce qui n'est pas conforme aux habitudes d'utilisation. Cette étape est obligatoire.

latitude_old = latitude.copy()
t2m_old = t2m.copy()
nlats = len(latitude)
for i in range(nlats):
    latitude[i] = latitude_old[nlats-1-i]
    print(nlats-1-i, latitude_old[nlats-1-i])
    t2m[i,:] = t2m_old[nlats-1-i,:]

5. Filtrer les stations dans la plage de grille (pas obligatoire)

Filtrez les sites qui se trouvent uniquement dans la plage de points de grille, et nous n'interpolerons pas les sites qui ne se trouvent pas dans la plage de points de grille ;
此情况适用条件:站点数据范围比格点的数据范围大

# ERA5数据经纬度范围
lonMin = np.min(longitude)
lonMax = np.max(longitude)
latMin = np.min(latitude)
latMax = np.max(latitude)

#筛选范围内的气象站点
stations_info =  stations_info[stations_info["经度"] >= lonMin] 
stations_info =  stations_info[stations_info["经度"] <= lonMax] 
stations_info =  stations_info[stations_info["纬度"] >= latMin] 
stations_info =  stations_info[stations_info["纬度"] <= latMax] 

lonSta = stations_info['经度'].to_numpy()
latSta = stations_info['纬度'].to_numpy()

6. Explication de la fonction searchsorted

insérez la description de l'image ici
insérez la description de l'image ici


7. Calcul d'interpolation d'interpolation bilinéaire

Compte tenu de la représentativité, l'interpolation du voisin le plus proche est recommandée et l'interpolation bilinéaire équivaut à un lissage unique.

# 定义一个方法
def Bilinear_interp(lonSta, latSta, longitude, latitude, var):
    var_sta = []
    for i in range(len(lonSta)):
        iSta = np.searchsorted(longitude, lonSta[i]) 
        if longitude[iSta] > lonSta[i]:
            iSta = iSta - 1 # 经度左下角点在经度array里的索引
            
        jSta = np.searchsorted(latitude, latSta[i])
        if latitude[jSta] > latSta[i]:
            jSta = jSta - 1 # 纬度左下角点在纬度array里的索引
        
        var11 = var[jSta, iSta]      #### t2m -> var
        var21 = var[jSta, iSta+1]
        var12 = var[jSta+1, iSta]
        var22 = var[jSta+1, iSta+1]

		# 改变变量名,为了公式计算时候方便
        x = lonSta[i]
        y = latSta[i]
        x1 = longitude[iSta]
        x2 = longitude[iSta+1]
        y1 = latitude[jSta]
        y2 = latitude[jSta+1]
        arg   = 1.0 / ((x2 - x1)*(y2 - y1))
        arg11 = arg * (x2 - x) * (y2 - y) 
        arg21 = arg * (x - x1) * (y2 - y)
        arg12 = arg * (x2 - x) * (y - y1)
        arg22 = arg * (x - x1) * (y - y1)
        var_interp = arg11*var11  + arg21*var21 + arg12*var12 + arg22*var22
        var_sta.append(var_interp)
    return var_sta
t2m_sta_bilinear = Bilinear_interp(lonSta, latSta, longitude, latitude, t2m)

stations_info['t2m_bilinear'] = np.array(t2m_sta_bilinear)
stations_info.index = range(len(lonSta))
stations_info.to_excel('weather_station_data.xlsx', sheet_name='Sheet1')

Je suppose que tu aimes

Origine blog.csdn.net/qq_35240689/article/details/129547171
conseillé
Classement