{"id":2137,"library":"netcdf4","title":"netCDF4 Python Interface","description":"The netCDF4-python library provides an object-oriented Python interface to the netCDF C library, enabling interaction with NetCDF version 4 and older NetCDF 3 format files. It leverages HDF5 for advanced features like hierarchical groups, zlib compression, and new data types. Currently at version 1.7.4, the library is actively maintained with frequent releases, including several minor updates and patches each year.","status":"active","version":"1.7.4","language":"en","source_language":"en","source_url":"https://github.com/Unidata/netcdf4-python","tags":["netcdf","data-science","scientific-computing","hdf5","geospatial","climate","meteorology","oceanography","numpy"],"install":[{"cmd":"pip install netCDF4","lang":"bash","label":"PyPI (recommended)"},{"cmd":"conda install -c conda-forge netcdf4","lang":"bash","label":"Conda (recommended for easier dependency management)"}],"dependencies":[{"reason":"Essential for numerical array manipulation and data storage within NetCDF variables.","package":"numpy","optional":false},{"reason":"Provides datetime objects that handle calendar systems and dates outside the standard Gregorian range, often used in climate data.","package":"cftime","optional":false},{"reason":"Required for locating SSL certificates, enabling access to OPeNDAP HTTPS URLs since version 1.6.4.","package":"certifi","optional":false},{"reason":"The core underlying C library that `netcdf4-python` interfaces with. Binary wheels often bundle this, but source installs or specific environments may require manual installation and configuration (e.g., via `nc-config`).","package":"netCDF C library","optional":false},{"reason":"NetCDF-4 format is built on HDF5. Similar to the NetCDF C library, this may require manual installation for source builds.","package":"HDF5 C library","optional":false},{"reason":"Optional. Required for parallel I/O capabilities when working in an MPI environment.","package":"mpi4py","optional":true},{"reason":"Optional. Required if building `netcdf4` from source.","package":"Cython","optional":true}],"imports":[{"note":"The primary class for opening, creating, and interacting with NetCDF files.","symbol":"Dataset","correct":"from netCDF4 import Dataset"}],"quickstart":{"code":"import os\nfrom netCDF4 import Dataset\nimport numpy as np\n\n# Define a dummy NetCDF file path\nfilename = 'example.nc'\n\n# Create a new NetCDF file in write mode ('w')\nwith Dataset(filename, 'w', format='NETCDF4') as nc_file:\n    # Create dimensions\n    nc_file.createDimension('x', 10)\n    nc_file.createDimension('y', 5)\n    nc_file.createDimension('time', None) # 'None' for unlimited dimension\n\n    # Create variables\n    x_var = nc_file.createVariable('x', 'i4', ('x',))\n    y_var = nc_file.createVariable('y', 'i4', ('y',))\n    time_var = nc_file.createVariable('time', 'f8', ('time',))\n    data_var = nc_file.createVariable('temperature', 'f4', ('time', 'y', 'x'))\n\n    # Add attributes to variables\n    data_var.units = 'Celsius'\n    data_var.long_name = 'Air Temperature'\n\n    # Write data to variables\n    x_var[:] = np.arange(10)\n    y_var[:] = np.arange(5)\n    \n    # Write data for the first time step\n    time_var[0] = 0.0\n    data_var[0, :, :] = np.random.rand(5, 10) * 30 + 273.15 # Kelvin example\n    \n    # Write data for a second time step (demonstrates unlimited dimension)\n    time_var[1] = 1.0\n    data_var[1, :, :] = np.random.rand(5, 10) * 30 + 273.15\n\n    print(f\"Successfully created and wrote to {filename}\")\n\n# Read data from the NetCDF file in read mode ('r')\nwith Dataset(filename, 'r') as nc_file:\n    print(f\"\\nOpened {filename} for reading:\")\n    print(f\"File format: {nc_file.data_model}\")\n    print(f\"Dimensions: {list(nc_file.dimensions.keys())}\")\n    print(f\"Variables: {list(nc_file.variables.keys())}\")\n\n    temp_data = nc_file.variables['temperature'][:, :, :]\n    print(f\"Shape of 'temperature' data: {temp_data.shape}\")\n    print(f\"Units of 'temperature': {nc_file.variables['temperature'].units}\")\n    print(f\"Sample temperature data:\\n{temp_data[0, 0, 0]:.2f} {nc_file.variables['temperature'].units}\")\n\n# Clean up the created file\nos.remove(filename)\nprint(f\"\\nCleaned up {filename}\")","lang":"python","description":"This quickstart demonstrates how to create a NetCDF4 file, define dimensions (including an unlimited dimension for time), create variables with attributes, write NumPy array data into these variables, and then read the data back. It uses `Dataset` for file operations and `numpy` for data generation."},"warnings":[{"fix":"Users must ensure that all calls to `netCDF4` library functions are made from a single thread, or implement external threading locks if concurrent access is absolutely necessary.","message":"Starting with version 1.7.4 and when using free-threaded Python (e.g., Python 3.13+ with `PYTHON_FREETHREADING=1`), `netcdf4-python` may experience segfaults if `netCDF4` functions are called from multiple threads concurrently. The underlying `netcdf-c` library is not thread-safe, and while `netcdf4-python` has internal locking, care must be taken.","severity":"breaking","affected_versions":">=1.7.4 (especially with free-threaded Python)"},{"fix":"For ease of installation, use `conda` (`conda install netcdf4`) or ensure your system has the `netCDF C` and `HDF5 C` libraries installed and discoverable by the Python build process (e.g., by setting `NETCDF4_DIR` or `LD_LIBRARY_PATH`).","message":"Installation via `pip` usually provides pre-compiled binary wheels that bundle the necessary `netCDF C` and `HDF5 C` libraries. However, if building from source, or on less common systems, these external C libraries must be installed separately and configured correctly (e.g., via `nc-config` or environment variables) for `netcdf4-python` to compile and function.","severity":"gotcha","affected_versions":"All versions (especially when not using pre-built wheels)"},{"fix":"To revert to the pre-1.4.0 behavior (return unmasked NumPy arrays unless missing values are present), use `Dataset.set_auto_mask(False)` or `Variable.set_auto_mask(False)` after opening the dataset. Alternatively, adapt your code to expect masked arrays by default.","message":"Prior to version 1.4.0, `netcdf4-python` would only return masked arrays if a slice of data explicitly contained missing values. From version 1.4.0 onwards, the default behavior changed to always return masked arrays for primitive and enum data types if `missing_value` or `_FillValue` attributes are defined, regardless of whether the slice contains actual missing data.","severity":"breaking","affected_versions":">=1.4.0"},{"fix":"Replace `datetime.datetime.utcnow()` with `datetime.datetime.now(datetime.timezone.utc)` for timezone-aware UTC datetimes, or `datetime.datetime.now(datetime.UTC)` in Python 3.11+. Remember to import `datetime` and `timezone` from the `datetime` module.","message":"Many examples and older codebases use `datetime.datetime.utcnow()` when assigning time attributes (e.g., to `nc.history`). Python's `datetime.utcnow()` is deprecated and will raise `DeprecationWarning` in modern Python versions, scheduled for removal in future versions.","severity":"deprecated","affected_versions":"All versions, when used with Python versions where `utcnow()` is deprecated (Python 3.11+)"},{"fix":"If encountering issues with remote OPeNDAP file access on these specific versions, upgrade to a newer patch release (e.g., 1.7.2 or later) or downgrade to a stable prior version (e.g., 1.6.5).","message":"Versions 1.7.0 and 1.7.1 introduced a regression that prevented opening remote OPeNDAP files, resulting in `curl` errors. This issue was likely resolved in subsequent patch releases.","severity":"breaking","affected_versions":"1.7.0, 1.7.1"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}