我有两个数据集(分别称为satdata和atmosdata)。 Atmosdata在纬度和经度上均匀分布。 Atmosdata的尺寸(纬度:713,等级:37,经度:1440,时间:72),总大小为12GB。 Atmosdata具有多个变量,例如温度,湿度等。湿度的形状为(时间,水平,纬度,经度)。
Satdata包含卫星观测数据,其维度为(across_track:90,channel:3,time:32195),其中包含90 * 3 * 32195 = 8692650个数据点。 Across_track是指跨轨道位置的卫星视场。 Satdata在纬度/经度上的网格不均匀。例如,satdata.latitude的维度为(时间,频道,cross_track),与satdata.longitude,satdata.sft的维度相同。
Atmosdata和satdata中的'time'变量包含同一天的时间,但是这两个数据集中的值不同。我需要找到与satdata具有相同纬度,经度和时间的atmosdata(例如,湿度和温度)。
为了实现这一点,我遍历了satdata来找到每个观测的位置和时间;然后我找到相应的atmosdata(首先是距卫星数据位置最近的网格,然后插值至卫星时间)。最后,我将所有迭代的结果atmosdata连接到一个数据集中。
通过使用一小段数据,我的代码的一部分如下。
import xarray as xr
import numpy as np
import dask
import pandas as pd
# define a simple satdata dataset
lon = np.array([[18.717, 18.195, 17.68 ], [18.396, 17.87 , 17.351, ]])
lat = np.array([[-71.472, -71.635, -71.802],
[-71.52 , -71.682, -71.847]])
sft = np.array([[1, 1, 1],
[1, 1, 1]])
time = np.array(['2010-09-07T00:00:01.000000000', '2010-09-07T00:00:03.000000000'],dtype='datetime64[ns]')
satdata = xr.Dataset({'sft': (['time','across_track'], sft)}, coords = {'longitude': (['time','across_track'], lon), 'latitude': (['time','across_track'], lat), 'time':time })
# atmosdata
atmoslat = np.array([-71.75, -71.5 , -71.25, -71. , -70.75, -70.5 , -70.25, -70. , -69.75 ])
atmoslon = np.array([17.25, 17.5 , 17.75, 18. , 18.25, 18.5 , 18.75, 19. , 19.25])
atmostime = np.array(['2010-09-07T00:00:00.000000000', '2010-09-07T01:00:00.000000000'],dtype='datetime64[ns]')
atmosq = np.random.rand(2,9,9)
atmosdata = xr.Dataset({'q': (['time', 'latitude', 'longitude'], atmosq)}, coords={'longitude':(['longitude'], atmoslon), 'latitude': (['latitude'], atmoslat), 'time':(['time'], atmostime)})
# do the matching:
matched = dask.compute(match(atmosdata, satdata),scheduler='processes', num_workers=20)[0]
匹配功能如下:
@dask.delayed
def match(atmosdata, satdata):
newatmos = []
newind = 0
# iterate over satdata
for i in np.ndenumerate(satdata.sft):
if i[1] != np.nan:
# find one latitude and longitude of satellite data
temp_lat = satdata.latitude.isel(time=[i[0][0]], across_track=[i[0][1]])
temp_lon = satdata.longitude.isel(time=[i[0][0]], across_track=[i[0][1]])
# find the atmosdata in the grid nearest to this location
temp_loc = atmosdata.sel(latitude =temp_lat.values.ravel()[0], longitude = temp_lon.values.ravel()[0], method='nearest')
if temp_loc.q.all() > 0:
# find atmosdata at the satellite time by interpolation
temp_time = satdata.time.isel(time=[i[0][0]])
newatmos.append(temp_loc.interp( time = temp_time.data.ravel() ))
newind += 1
return xr.concat(newatmos,dim=pd.Index(range(newind), name='NewInd'))
1)当我启动代码时,它可以工作。但是,如果我没有在代码中使用较小的数据量,而是使用原始数据(具有上述尺寸),则会启动计算并出现错误。
---> 52 matched = dask.compute(match(ecmwfdata, ssmis_land), scheduler='processes', num_workers=20 )
error: 'i' format requires -2147483648 <= number <= 2147483647
2)如果我使用其他维度的数据集,satdata(跨轨:90,通道:3,时间:100)和atmosdata(纬度:71,级别:37,经度:1440,时间:72),则计算需要很长时间。我想我的编码不是使用DASK快速解决此问题的最佳方法。
2)是否有比使用for循环更好的方法? for循环可能无法利用DASK进行快速计算?
3)对satdata进行分块,然后在一块satdata中找到纬度和经度的限制,然后根据此限制对atmosdata进行分块,最后将match函数应用于每个satdata块,是否是一个好主意?和atmosdata?如果这是个好主意,我还不知道如何手动遍历每个satdata块。...
4)该函数使用两个参数,即satdata和atmosdata。由于这两个数据集可能很大(对于atmosdata,数据集为12G),那么计算会更慢吗?
5)在函数中,我必须在选择中使用.value,这在使用大输入数据时是否会减慢计算速度?
谢谢!
最诚挚的问候
小艾
答案 0 :(得分:0)
除了说我认为您需要使用使用距离树的重采样程序包之外,我不确定是否能提供帮助
https://github.com/pytroll/pyresample
Pyresample有一个网格状网格,应该可以做您想要的
我已经使用https://github.com/storpipfugl/pykdtree来找到最近的点