NetCDF Files: Scientific Array Data for Climate and Oceanography
NetCDF (Network Common Data Form) is the dominant file format for large-scale scientific array data, particularly in atmospheric science, oceanography, climate research, hydrology, and geophysics. Developed by Unidata (part of UCAR — the University Corporation for Atmospheric Research) starting in 1988, NetCDF was designed to store multidimensional array data — think temperature, pressure, salinity, or wind velocity measured at thousands of grid points over time — in a self-describing, portable, and scalable format. A single NetCDF file can describe terabytes of climate model output, ship a complete dataset with coordinate systems attached, and remain readable on any platform decades later.
What Makes NetCDF Different
Self-Describing
Every NetCDF file carries its own documentation. Variables have names (air_temperature, sea_surface_salinity), units (K, psu), long descriptions, missing value indicators, and standard metadata attributes. A researcher receiving a NetCDF file can understand its contents without a separate README:
netcdf temperature_2024 {
dimensions:
time = UNLIMITED ;
lat = 180 ;
lon = 360 ;
lev = 27 ;
variables:
float time(time) ;
time:units = "hours since 2024-01-01 00:00:00" ;
time:calendar = "gregorian" ;
float lat(lat) ;
lat:units = "degrees_north" ;
lat:standard_name = "latitude" ;
float lon(lon) ;
lon:units = "degrees_east" ;
float air_temperature(time, lev, lat, lon) ;
air_temperature:units = "K" ;
air_temperature:long_name = "Air Temperature" ;
air_temperature:missing_value = -9999.f ;
air_temperature:_FillValue = -9999.f ;
}
Coordinate-Aware
NetCDF coordinates are not just integers — they carry physical meaning. A grid point at index [42, 73] maps to latitude 42°N and longitude 73°E. Time coordinates carry calendar information. Pressure levels carry units. This coordinate awareness enables operations like "give me all temperatures at 500 hPa over Europe in January 2020" without knowing how data is indexed internally.
Portable Binary
NetCDF files are binary, not plain text, but they are entirely platform-independent. Byte order (endianness), floating-point representation, and data types are normalized. A file written on a Cray supercomputer in 1995 reads correctly on a modern ARM laptop.
Supports Huge Datasets
The UNLIMITED dimension in the example above means the time axis can grow indefinitely. A climate simulation can append new time steps to an existing file without rewriting the whole file. NetCDF4 (based on HDF5) supports chunking and compression, enabling efficient access to any slice of a terabyte dataset.
NetCDF Versions
NetCDF Classic (NetCDF-3): The original format. Simple structure, widely supported. 2 GB file size limit (32-bit offset) or 4 GB (64-bit offset classic). No compression.
NetCDF-4: Based on HDF5 container format. Removes size limits, adds groups (hierarchical structure), supports chunking, multiple compression algorithms (zlib, szip), and per-variable compression. Most new scientific datasets use NetCDF-4.
NetCDF-4 Classic Model: Uses the HDF5 container but restricts features to NetCDF Classic semantics — a bridge format for tools that need NetCDF-3 compatibility but want HDF5 compression.
Reading and Writing NetCDF
Python (xarray + netCDF4)
xarray is the de facto standard for working with NetCDF in Python. It provides labeled, N-dimensional arrays with coordinate-aware operations:
import xarray as xr
# Open a NetCDF file
ds = xr.open_dataset('temperature_2024.nc')
# Inspect contents
print(ds)
# <xarray.Dataset>
# Dimensions: (time: 8760, lev: 27, lat: 180, lon: 360)
# Coordinates: ...
# Select a spatial subset
europe = ds.sel(lat=slice(35, 70), lon=slice(-10, 40))
# Select a specific pressure level and time
T_500hPa_jan = ds['air_temperature'].sel(
lev=500.0,
time=slice('2024-01-01', '2024-01-31')
)
# Calculate monthly mean
monthly_mean = ds['air_temperature'].resample(time='1ME').mean()
# Save to a new NetCDF file
monthly_mean.to_netcdf('monthly_mean_temp.nc')
Python (netCDF4 library, lower level)
from netCDF4 import Dataset
import numpy as np
# Read
nc = Dataset('data.nc', 'r')
temps = nc.variables['air_temperature'][:] # returns masked array
lats = nc.variables['lat'][:]
lons = nc.variables['lon'][:]
nc.close()
# Write
nc_out = Dataset('output.nc', 'w', format='NETCDF4')
nc_out.createDimension('lat', 180)
nc_out.createDimension('lon', 360)
lat_var = nc_out.createVariable('lat', 'f4', ('lat',))
lat_var.units = 'degrees_north'
lat_var[:] = np.linspace(-89.5, 89.5, 180)
nc_out.close()
R (ncdf4 package)
library(ncdf4)
nc <- nc_open("data.nc")
temp <- ncvar_get(nc, "air_temperature")
lat <- ncvar_get(nc, "lat")
lon <- ncvar_get(nc, "lon")
nc_close(nc)
Fortran and C
The original NetCDF C library provides the reference implementation. Fortran90/95 bindings are widely used in climate model code. Most climate models (CESM, ICON, ECMWF-IFS) write NetCDF output via the C or Fortran libraries.
Command-Line Tools
ncdump (included with NetCDF installation): Converts NetCDF to human-readable CDL (Common Data form Language) text:
ncdump -h data.nc # header only (dimensions, variables, attributes)
ncdump -v lat,lon data.nc # header + specific variables
ncdump data.nc > data.cdl # full ASCII dump
ncinfo / ncdump -h for quick inspection.
NCO (NetCDF Operators): Command-line toolkit for arithmetic, averaging, and file manipulation:
ncwa -a time data.nc time_mean.nc # average over time
ncra *.nc annual_mean.nc # average multiple files
ncks -v air_temperature data.nc temp_only.nc # extract one variable
ncrcat Jan.nc Feb.nc Mar.nc Q1.nc # concatenate files along time
CDO (Climate Data Operators): Higher-level climate data processing:
cdo monmean data.nc monthly_means.nc # monthly means
cdo sellevel,500 data.nc 500hPa.nc # extract pressure level
cdo remapbil,r1440x720 data.nc out.nc # regrid to 0.25° resolution
CF Conventions
The Climate and Forecast (CF) Conventions define standardized variable names, units, and coordinate systems for NetCDF files used in climate and earth sciences. CF-compliant files use:
standard_nameattributes from the CF standard name table (air_temperature,sea_surface_height)unitsfollowing UDUNITS2 conventions- Coordinate system attributes (projection type, grid_mapping_name)
CF conventions enable interoperability: a tool written to process CF-compliant NetCDF can work with any CF dataset regardless of its source.
NetCDF vs. HDF5 vs. Zarr
| Feature | NetCDF Classic | NetCDF-4 (HDF5) | Zarr |
|---|---|---|---|
| Compression | ❌ | ✅ zlib/szip | ✅ Many codecs |
| Cloud-native | ❌ | Partial | ✅ Native |
| Groups | ❌ | ✅ | ✅ |
| Chunking | ❌ | ✅ | ✅ |
| Standard | ✅ Widely | ✅ Common | Growing |
| CF conventions | ✅ | ✅ | Partial |
Zarr is gaining ground for cloud-native scientific data (no sequential access requirement), but NetCDF remains the standard for archival, model output, and data sharing in the atmospheric sciences.
Related conversions
Frequent conversions across the catalogue: