python - xarray.open_rasterio 不能在列表理解中打开超过 ~400 个文件
问题描述
发生了什么:
当尝试使用 列表理解打开 14,000 个文件时xarray.open_rasterio
,循环永远不会完成。目标是打开所有这些 GeoTiff 文件,将波段维度更改为日期维度,按日期堆叠,然后另存为 .single .nc。它可以在列表理解中打开少于 400 个文件没有问题。在两台不同的 Linux 机器上就是这种情况。
但是,当我提前创建列表并使用常规 for 循环打开每个文件并将结果附加到列表时,它会在大约一分钟内按预期完成所有 14000 个文件。为什么使用列表理解时会出现性能差异/可能的错误?一般来说,我对 python 列表理解性能有什么遗漏吗?
此外,我使用 linux 命令lsof
很快确定在列表理解中,大约 446 个文件保持打开状态,而脚本从未完成。如果我继续检查,该值会在 446 左右波动lsof
(它列出了由带有 的进程打开的文件lsof -p
)。所以看起来有些文件没有在正常时间内关闭。
你期望发生的事情:我认为这需要大约一分钟,因为打开一个文件大约需要 41 毫秒。
最小完整可验证示例:数据文件夹 chirps-clipped 可在此处下载:https ://ucsb.box.com/s/erqz20bgojhvpw2xpdbbcs17e131xxe4
import xarray as xr
import rioxarray as rio
from pathlib import Path
from datetime import datetime
%matplotlib inline
all_scenes_f = Path('../rasters/chirps-clipped')
all_precip_paths = list(all_scenes_f.glob("*"))
# for some reason the fll value is not correct. this is the correct bad value to mask by
testf = all_precip_paths[0]
x = rio.open_rasterio(testf)
badvalue = np.unique(x.where(x != x._FillValue).sel(band=1))[0]
def chirps_path_date(path):
_, _, year, month, day, _ = path.name.split(".")
day = day.split("-")[0]
return datetime(int(year), int(month), int(day))
def open_chirps(path):
data_array = rio.open_rasterio(path) #chunks makes i lazyily executed
data_array = data_array.sel(band=1).drop("band") # gets rid of old coordinate dimension since we need bands to have unique coord ids
data_array["date"] = chirps_path_date(path) # makes a new coordinate
return data_array.expand_dims({"date":1}) # makes this coordinate a dimension
### each data file is small and isn't tiled so it is not a good idea to use chunking
# https://github.com/pydata/xarray/issues/2314
import rasterio
with rasterio.open(testf) as src:
print(src.profile)
%timeit rio.open_rasterio(testf)
### This is where the file opening bug happens
daily_chirps_arrs = [xr.open_rasterio(path) for path in all_precip_paths]
还有什么我们需要知道的吗?:
环境:
xr.show_versions() 的输出INSTALLED VERSIONS
------------------
commit: None
python: 3.8.5 | packaged by conda-forge | (default, Sep 16 2020, 18:01:20)
[GCC 7.5.0]
python-bits: 64
OS: Linux
OS-release: 5.4.0-53-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8
libhdf5: None
libnetcdf: None
xarray: 0.16.1
pandas: 1.1.4
numpy: 1.19.1
scipy: 1.5.2
netCDF4: None
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: None
cftime: None
nc_time_axis: None
PseudoNetCDF: None
rasterio: 1.1.6
cfgrib: None
iris: None
bottleneck: None
dask: 2.27.0
distributed: 2.30.1
matplotlib: 3.3.2
cartopy: None
seaborn: None
numbagg: None
pint: None
setuptools: 49.6.0.post20200917
pip: 20.2.3
conda: None
pytest: None
IPython: 7.18.1
sphinx: None