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()
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月份的数据
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.
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()
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月份的数据
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
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')