如何在全球NetCDF数据中掩膜/过滤非陆地值?(Python/NCO实现)
Got it, let's walk through how to mask your 0.25-degree CMORPH NetCDF data to keep only land values. I'll use Python tools since they're the most straightforward for this kind of geospatial task.
First, make sure you have the necessary packages installed. Open your terminal and run:
pip install xarray netCDF4 regionmask numpy
xarrayhandles NetCDF data easilyregionmaskgives us ready-to-use land-sea masks matched to common gridsnumpyhelps with coordinate handling
Start by loading your data and verifying the coordinates match what you described:
import xarray as xr # Load the dataset ds = xr.open_dataset("cmorph_global_daily.nc") # Check coordinates (should show lon: 0-360, lat: -60 to 60, 0.25-degree resolution) print(ds.lon.values[:5]) print(ds.lat.values[:5])
Your lat dimension is marked as UNLIMITED, but xarray will still handle it normally for masking.
We'll use regionmask's Natural Earth land mask, which aligns perfectly with your 0.25-degree, 0-360 longitude grid:
import regionmask import numpy as np # Generate the land mask: land areas get a region ID, ocean areas are NaN land_mask = regionmask.defined_regions.natural_earth.land_110.mask(ds.lon, ds.lat) # Convert to a boolean mask (True = land, False = ocean) if you prefer land_mask_bool = land_mask.notnull()
- Use
land_50orland_10instead ofland_110if you need higher-resolution land boundaries (note: these will take more memory to process)
Now apply the mask to keep only land values (set ocean values to NaN). Replace your_variable_name with the actual variable in your dataset (e.g., precip for CMORPH precipitation):
# Mask the dataset: keep land values, set ocean to NaN ds_land_masked = ds.where(land_mask_bool) # Verify the mask worked by checking a slice of data print(ds_land_masked.your_variable_name.isel(time=0).values)
Finally, save the masked dataset to a new NetCDF file:
ds_land_masked.to_netcdf("cmorph_global_daily_land_masked.nc")
Quick Troubleshooting Tips
- If your longitude was in -180 to 180 format, we'd need to convert it to 0-360 first, but you mentioned it's already full 360, so no extra steps needed
- If the mask doesn't align perfectly, manually define your coordinate grid and regenerate the mask:
lon = np.arange(0, 360, 0.25) lat = np.arange(-60, 60, 0.25) # Adjust if your lat stops at 59.75 instead of 60 land_mask = regionmask.defined_regions.natural_earth.land_110.mask(lon, lat)
内容的提问来源于stack exchange,提问作者James Adams




