2017-05-08 1 views
4

수천 개의 GRIB 파일이있는 디렉토리가 있다고 가정합니다. 내가 그들을 쿼리 할 수 ​​있도록 dask 배열에 그 파일을로드하고 싶습니다. 어떻게이 일을 할 수 있습니까? 아래의 시도는 효과가있는 것처럼 보이지만 각 GRIB 파일을 열어야하며 실행하는 데 오랜 시간이 걸리며 내 기억이 모두 필요합니다. 더 좋은 방법이 있어야합니다.GRIB 파일의 디렉토리를 Dask 배열에로드하는 방법

내 시도 : dask.delayed를 사용하는

import dask.array as da 
from dask import delayed 
import gdal 
import glob 
import os 


def load(filedir): 
    files = sorted(glob.glob(os.path.join(filedir, '*.grb'))) 
    data = [da.from_array(gdal.Open(f).ReadAsArray(), chunks=[500,500,500], name=f) for f in files] 
    return da.stack(data, axis=0) 

file_dir = ... 
array = load(file_dir) 
+0

xarray는 dask를 기반으로 작성되었으며 PyNIO를 통한 GRIB 지원은 현재 사용 가능합니까? 그러나 데이터를 빠르게 분석하려면 hdf5 또는 NetCDF4로 다시 작성해야하며 적절한 청킹을 사용하면 추가 분석이 매우 쉬워집니다. – kakk11

답변

4

가장 좋은 방법은이 작업을 수행 할 수는있을 것이다. 이 경우 지연된 함수를 만들어 배열을 읽은 다음 da.from_delayed 함수를 사용하여 delayed 개체에서 dask 배열을 작성합니다.

각 파일을로드하는 데 하나의 작업이 있음에 유의하십시오. 개별 파일이 큰 경우 load 함수에서 직접 파일을 청크 할 수 있습니다. 나는 gdal에 익숙하지 않지만, ReadAsArray 방법에 대한 간략한 설명으로 xoff/yoff/xsize/ysize 매개 변수 (확실하지 않음)로 수행 할 수 있습니다. 이 코드는 직접 작성해야하지만 큰 파일의 경우 더 효과적 일 수 있습니다.

위 코드를 사용하여 rechunk으로 전화하면 작은 청크로 다시 채울 수 있습니다. 이것은 여전히 ​​하나의 태스크에서 각 파일을 읽는 결과를 가져 오지만, 후속 단계는 더 작은 청크에서 작동 할 수 있습니다. 이것이 가치가 있는지 여부는 개별 파일의 크기에 따라 다릅니다.

x = x.rechunk((500, 500, 500)) # or whatever chunks you want 
+0

코드는 60 개의 파일을 실행할 때 작동합니다. 17,500 개 이상의 파일을 실행하려고하면 메모리 오류가 발생합니다. 각 파일에는 차원 (52, 224, 464)이 있습니다. 그들을 쌓은 후 (1, 1, 224, 464) 청크 크기로 rechunked. 내가하는 x는'x [:, :, 80, 80] .compute()'입니다. 또 다른 중요한 세부 사항은 디스크에 스필 할 캐시를 제공한다고해서 메모리 오류가 방지되지 않는다는 것입니다. –

+0

이 경우 rechunking은 실제로 의미가 없습니다. 하위 집합을 나중에 선택하기 만하면됩니다. 일반적으로 개별 작업의 비용이 스케줄러의 오버 헤드보다 훨씬 크도록 청크를 충분히 크게 유지하려고합니다. 자세한 내용은 http://dask.pydata.org/en/latest/array-creation.html#chunks를 참조하십시오. 괜찮은 규칙은 각 청크에서 적어도 1e6 요소이며 일반적으로 그 이상입니다. 난 전혀 rechunk, 그리고 파일 당 청크가. –

+0

rechunking 할 때 파일의 blocksize (chunksize)도 검사하십시오. 기본 블록 크기 (또는 여러 개)를 고려하면 실제로 성능이 향상 될 수 있습니다. 동일한 데이터를 디스크에서 반복해서 읽지 못하게합니다. GDAL의 블록 캐시는 또한이를 방지하는 데 도움이됩니다. –

관련 문제