netCDF4 file access via h5py with hierarchical and legacy APIs for scientific computing
69
Dimensions define the coordinate system and shape constraints for variables in netCDF4 files. They can be fixed-size or unlimited, and serve as the foundation for all variable definitions and data organization.
Create and manage dimensions within groups.
class Dimensions(MutableMapping):
def __getitem__(self, name: str) -> Dimension:
"""Get dimension by name."""
...
def __setitem__(self, name: str, size: int) -> None:
"""Create new dimension with specified size."""
...
def __delitem__(self, name: str) -> None:
"""Remove dimension (if not used by variables)."""
...
def __contains__(self, name: str) -> bool:
"""Check if dimension exists."""
...
def __iter__(self):
"""Iterate over dimension names."""
...
def __len__(self) -> int:
"""Number of dimensions in this group."""
...Individual dimension properties and methods.
class Dimension:
def __init__(self, parent: Group, name: str, size: int = None,
create_h5ds: bool = False, phony: bool = False):
"""
Create or access a dimension.
Args:
parent (Group): Parent group containing this dimension
name (str): Dimension name
size (int): Dimension size (None for unlimited)
create_h5ds (bool): Create HDF5 dimension scale
phony (bool): Whether this is a phony dimension
"""
...
@property
def name(self) -> str:
"""Dimension name."""
...
@property
def size(self) -> int:
"""Current dimension size."""
...
def isunlimited(self) -> bool:
"""Check if dimension is unlimited."""
...
def group(self) -> Group:
"""Return parent group."""
...Advanced dimension operations and utilities.
def add(self, name: str) -> None:
"""Add existing dimension from parent groups."""
...
def add_phony(self, name: str, size: int) -> None:
"""Add phony dimension for unlabeled axes."""
...
def resize_dimension(self, dim: str, size: int) -> None:
"""Resize unlimited dimension."""
...import h5netcdf
with h5netcdf.File('dimensions.nc', 'w') as f:
# Create fixed-size dimensions
f.dimensions['lat'] = 180
f.dimensions['lon'] = 360
f.dimensions['level'] = 50
# Create unlimited dimension
f.dimensions['time'] = None # None indicates unlimited
# Access dimension properties
lat_dim = f.dimensions['lat']
print(f"Latitude dimension size: {lat_dim.size}")
print(f"Is unlimited: {lat_dim.isunlimited()}")
# Check if dimension exists
if 'time' in f.dimensions:
time_dim = f.dimensions['time']
print(f"Time is unlimited: {time_dim.isunlimited()}")
# List all dimensions
print(f"Dimensions: {list(f.dimensions.keys())}")
print(f"Number of dimensions: {len(f.dimensions)}")with h5netcdf.File('unlimited.nc', 'w') as f:
# Create unlimited dimension
f.dimensions['time'] = None
f.dimensions['station'] = 100
# Create variable using unlimited dimension
temp = f.create_variable('temperature', ('time', 'station'), dtype='f4')
# Initially, unlimited dimension has size 0
print(f"Initial time size: {f.dimensions['time'].size}")
# Writing data extends the unlimited dimension
temp[0, :] = np.random.random(100)
print(f"After first write: {f.dimensions['time'].size}")
temp[1, :] = np.random.random(100)
print(f"After second write: {f.dimensions['time'].size}")
# Can explicitly resize unlimited dimensions
f.resize_dimension('time', 10)
print(f"After resize: {f.dimensions['time'].size}")with h5netcdf.File('coordinates.nc', 'w') as f:
# Create dimensions
f.dimensions['x'] = 100
f.dimensions['y'] = 50
f.dimensions['time'] = None
# Create coordinate variables (same name as dimension)
x_coord = f.create_variable('x', ('x',), dtype='f4')
x_coord[:] = np.linspace(0, 99, 100)
x_coord.attrs['units'] = 'm'
x_coord.attrs['long_name'] = 'X coordinate'
y_coord = f.create_variable('y', ('y',), dtype='f4')
y_coord[:] = np.linspace(0, 49, 50)
y_coord.attrs['units'] = 'm'
y_coord.attrs['long_name'] = 'Y coordinate'
# Time coordinate (unlimited)
time_coord = f.create_variable('time', ('time',), dtype='f8')
time_coord.attrs['units'] = 'days since 2023-01-01'
time_coord.attrs['calendar'] = 'standard'
# Data variable using these dimensions
data = f.create_variable('temperature', ('time', 'y', 'x'), dtype='f4')
# Write time series data
for t in range(5):
time_coord[t] = t
data[t, :, :] = np.random.random((50, 100)) * 30 + 273.15with h5netcdf.File('groups_dims.nc', 'w') as f:
# Create dimensions in root group
f.dimensions['time'] = None
f.dimensions['lat'] = 180
f.dimensions['lon'] = 360
# Create child group
surface = f.create_group('surface')
# Child group can use parent dimensions
surface.dimensions.add('time') # Reference parent's time dimension
surface.dimensions.add('lat') # Reference parent's lat dimension
surface.dimensions.add('lon') # Reference parent's lon dimension
# Or create group-specific dimensions
surface.dimensions['height'] = 10
# Create variable using mixed dimensions
temp = surface.create_variable(
'temperature',
('time', 'height', 'lat', 'lon'),
dtype='f4'
)
print(f"Root dimensions: {list(f.dimensions.keys())}")
print(f"Surface dimensions: {list(surface.dimensions.keys())}")with h5netcdf.File('check_usage.nc', 'r') as f:
for dim_name, dimension in f.dimensions.items():
print(f"Dimension: {dim_name}")
print(f" Size: {dimension.size}")
print(f" Unlimited: {dimension.isunlimited()}")
# Find variables using this dimension
using_vars = []
for var_name, variable in f.variables.items():
if dim_name in variable.dimensions:
using_vars.append(var_name)
print(f" Used by variables: {using_vars}")
# Check if coordinate variable exists
if dim_name in f.variables:
coord_var = f.variables[dim_name]
print(f" Has coordinate variable: {coord_var.dtype}")
else:
print(f" No coordinate variable")# Phony dimensions handle unlabeled axes in HDF5 files
with h5netcdf.File('unlabeled.nc', 'r', phony_dims='sort') as f:
# If file has unlabeled dimensions, they get phony names
for dim_name, dimension in f.dimensions.items():
if hasattr(dimension, 'phony') and dimension.phony:
print(f"Phony dimension: {dim_name} (size: {dimension.size})")with h5netcdf.File('validate.nc', 'w') as f:
try:
# This will work
f.dimensions['valid_name'] = 100
# This might cause issues depending on backend
# f.dimensions[''] = 50 # Empty name
# Creating variable with non-existent dimension will fail
# f.create_variable('test', ('nonexistent',), dtype='f4')
except Exception as e:
print(f"Validation error: {e}")# Note: NetCDF4 format supports multiple unlimited dimensions
with h5netcdf.File('multi_unlimited.nc', 'w') as f:
# Multiple unlimited dimensions (netCDF4 feature)
f.dimensions['time'] = None
f.dimensions['ensemble'] = None
f.dimensions['lat'] = 90
f.dimensions['lon'] = 180
# Variable with multiple unlimited dimensions
temp = f.create_variable(
'temperature',
('time', 'ensemble', 'lat', 'lon'),
dtype='f4'
)
# Write data to extend both unlimited dimensions
temp[0, 0, :, :] = np.random.random((90, 180))
temp[1, 2, :, :] = np.random.random((90, 180))
print(f"Time size: {f.dimensions['time'].size}")
print(f"Ensemble size: {f.dimensions['ensemble'].size}")Install with Tessl CLI
npx tessl i tessl/pypi-h5netcdfdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10