私は 2 つのデータセット (satdata と atmosdata と呼ばれます) を持っています。Atmosdata は、緯度と経度で均等にグリッド化されています。Atmosdata はディメンション (緯度: 713、レベル: 37、経度: 1440、時間: 72) を持ち、合計サイズは 12GB です。Atmosdata には、温度、湿度などのいくつかの変数があります。湿度は、(時間、レベル、緯度、経度) の形をしています。
Satdata には衛星観測が含まれており、(across_track: 90、channel: 3、time: 32195) の次元があり、90*3*32195=8692650 ポイントのデータがあります。Across_track は、トラック位置を横切る衛星 FOV を意味します。Satdata は、緯度/経度で均等にグリッド化されていません。たとえば、satdata.latitude には (time, channel, across_track) の次元があり、satdata.longitude、satdata.sft と同じです。
Atmosdata と satdata の「time」変数には同じ日の時間が含まれていますが、これら 2 つのデータセットでは値が異なります。satdata と同じ緯度、経度、時刻を持つ atmosdata (湿度と温度など) を見つける必要があります。
これを実現するために、satdata を繰り返し処理して、各観測の場所と時間を見つけます。次に、対応する atmosdata を見つけます (最初に衛星データの場所に最も近いグリッド、次に衛星時間に補間されます)。最後に、すべての反復から得られた atmosdata を 1 つのデータセットに連結します。
私のコードの一部は、小さなデータを使用して次のようになります。
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 (across_track: 90、channel: 3、time: 100)、および atmosdata (緯度: 71、レベル: 37、経度: 1440、時間: 72) を使用すると、計算に非常に時間がかかります。時間。私のコーディングは、この問題を迅速に解決するために DASK を使用するには最適ではないと思います。
2) for ループを使用するよりも良い方法はありますか? for ループは、迅速な計算の目的で DASK を利用しない場合があります。
3) satdata をチャンクし、satdata のチャンクで緯度と経度の制限を見つけ、この制限に従って atmosdata をチャンクし、最後に satdata と atmosdata の各チャンクに match 関数を適用するのは良い考えでしょうか? これが良いアイデアである場合、satdata の各チャンクを手動で反復処理する方法はまだわかりません....
4) この関数は、satdata と atmosdata の 2 つの引数を使用します。これら 2 つのデータセットは非常に大きくなる可能性があるため (atmosdata の場合は 12G)、計算は遅くなりますか?
5) 選択で .value を使用しなければならなかった関数では、大きな入力データを使用すると、計算が遅くなりますか?
前もって感謝します !
よろしくお願いします
シャオニ