我有一个网格化的天气数据集,其尺寸为33 X 77 X 77.第一个维度是时间,其余分别是Lat和Lon。我需要每次将数据插入(线性或最近邻居)到不同的点(lat& lon)并将其写入csv文件。我已经使用了scipy的interp2d函数,它成功了一步。由于我在很多地方,我不想随着时间的推移而循环。
下面显示的是我写的一段代码,任何人都可以建议一个更好的方法来完成任务吗?import sys ; import numpy as np ; import scipy as sp ; from scipy.interpolate import interp2d ;import datetime ; import time ; import pygrib as pg ;
grb_f=pg.open('20150331/gfs.20150331.grb2') lat=tmp[0].data(lat1=4,lat2=42,lon1=64,lon2=102)[1] ; lat=lat[:,0];
lon=tmp[0].data(lat1=4,lat2=42,lon1=64,lon2=102)[2] ; lon=lon[0,:] ;
temp=np.empty((0,lon.shape[0]))
for i in range(0,tmp.shape[0]):
dat=tmp[i].data(lat1=4,lat2=42,lon1=64,lon2=102)
temp=np.concatenate([temp,dat[0]-273.15],axis=0)
temp1=temp.reshape(tmp.shape[0],lat.shape[0],lon.shape[0])
x=77 ; y=28 #(many points)
f=interp2d(lon,lat, temp1[0,:,:],kind='linear',copy=False,bounds_error=True ) ; Z=f(x,y)
编辑::
我没有制作3D矩阵,而是垂直添加数据并制作大小为2541 X 77的数据矩阵以及大小为2541 X 1的lat和lon.interp2d函数给出无效长度误差。
f=interp2d(lon,lat, temp1[0,:,:],kind='linear',copy=False,bounds_error=True )
"非矩形网格的输入z的长度无效")
ValueError:非矩形网格的输入z的长度无效
我的x,y,z矩阵的长度是相同的(2541,2541,2541)。那为什么会抛出一个错误? 可以解释一下吗?我们将非常感谢您的帮助。
答案 0 :(得分:1)
使用RedBlackPy非常容易处理时间序列。
import datetime as dt
import redblackpy as rb
index = [dt.date(2018,1,1), dt.date(2018,1,3), dt.date(2018,1,5)]
lat = [10.0, 30.0, 50.0]
# create Series object
lat_series = rb.Series(index=index, values=lat, dtype='float32',
interpolate='linear')
# Now you can access at any key using linear interpolation
# Interpolation does not create new items in Series
# It uses neighbours to calculate value inplace when you call getitem
print(lat_series[dt.date(2018,1,2)]) #prints 20
因此,如果您只想将内插值写入csv文件,则可以遍历所需键的列表并调用Series对象的getitem,然后将值放入文件:
# generator for dates range
def date_range(start, stop, step=dt.timedelta(1)):
it = start - step
while it < step:
it += step
yield it
#------------------------------------------------
# create list for keeping output strings
out_data = []
# create output file
out_file = open('data.csv', 'w')
# add head for output table
out_data.append('Time,Lat\n')
for date in date_range(dt.date(2018,1,1), dt.date(2018,1,5)):
out_data.append( '{:},{:}\n'.format(date, lat_series[date]) )
# write output Series
out_file.writelines(out_data)
out_file.close()
以同样的方式将其添加到处理Lon数据中。
答案 1 :(得分:0)
如果每次使用相同的lat和lon,你可以使用切片和手动插值来完成。因此,如果你想在lat = 4.875,lon = 8.4(显然你需要缩放以匹配你的实际间距)的1D数组值(
)b = a[:,4:6, 8:10]
c = ((b[:,0,0] * 0.125 + b[:,0,1] * 0.875) * 0.6 + ((b[:,1,0] * 0.125 + b[:,1,1] * 0.875) * 0.4)
显然你可以在一条线上完成所有这一切,但它会更加丑陋
编辑以在每个时间段允许变量lat和lon。
lat = np.linspace(55.0, 75.0, 33)
lon = np.linspace(1.0, 25.0, 33)
data = np.linspace(18.0, 25.0, 33 * 77 * 77).reshape(33, 77, 77)
# NB for simplicity I map 0-360 and 0-180 rather than -180+180
# also need to ensure values on grid lines or edges work ok
lat_frac = lat * 77.0 / 360.0
lat_fr = np.floor(lat_frac).astype(int)
lat_to = lat_fr + 1
lat_frac -= lat_fr
lon_frac = lon * 77.0 / 180.0
lon_fr = np.floor(lon_frac).astype(int)
lon_to = lon_fr + 1
lon_frac -= lon_fr
data_interp = ((data[:,lat_fr,lon_fr] * (1.0 - lat_frac) +
data[:,lat_fr,lon_to] * lat_frac) * (1.0 - lon_frac) +
(data[:,lat_to,lon_fr] * (1.0 - lat_frac) +
data[:,lat_to,lon_to] * lat_frac) * lon_frac)
答案 2 :(得分:0)
如果您想创建一个“插补器”对象,并使用它来按顺序查询您需要的特定点,您可以在scipy.interpolate.Rbf
模块中获取战利品:
“用于径向基函数近似/ n维散乱数据插值的类。”
如果您调整时间和空间维度之间的比率,n-dimensional
适用于您的数据,scattered
意味着您也可以将其用于常规/统一数据。