Reading and writing npy files

This guide shows examples of reading and writing npy files via stdlib.

Reading npy files in Fortran

Numpy can store numpy arrays as binary files in npy format via numpy.save:

import numpy as np

array = np.logspace(0, 2, 60).reshape((6, 2, 5))
np.save("array.npy", array)

This file can be read from Fortran via the stdlib_io_npy module.

load_npy.f90
program demo_load
  use stdlib_io_npy, only: load_npy
  implicit none
  integer, parameter :: dp = selected_real_kind(15)
  real(dp), allocatable :: array(:, :, :)

  call load_npy("array.npy", array)

  print '(*(g0,1x))', "shape:", shape(array)
  ! shape: 5 2 6
end program demo_load

Note

Numpy supports two memory layouts for ndarrays, either right-to-left memory layout (C stride scheme, row major ordering) or left-to-right memory layout (Fortran stride scheme, column major ordering).

The load_npy routine will read arrays always in left-to-right memory layout as contiguous array, rather than preserving the shape and transposing a multidimensional array in case data in right-to-left layout is encountered. This is equivalent to using numpy.ascontiguousarray to transfer from right-to-left layout to left-to-right layout in Python.

In case the data mismatches in type or rank an error occurs, which can be handled gracefully by retrieving the optional status and message arguments.

load_npy_error.f90
program demo_load_error
  use stdlib_io_npy, only: load_npy
  implicit none
  real, allocatable :: array(:, :, :)
  integer :: stat
  character(len=:), allocatable :: message

  call load_npy("array.npy", array, stat, message)

  if (stat /= 0) then
    print '(a)', message
    ! File 'array.npy' contains data of type '<f8', but expected '<f4'
  end if
end program demo_load_error

Writing npy files from Fortran

With stdlib it is also possible to write arrays in npy format

save_npy.f90
program demo_load
  use stdlib_io_npy, only: save_npy
  use stdlib_math, only: logspace
  implicit none
  integer, parameter :: dp = selected_real_kind(15)
  real(dp), allocatable :: array(:, :, :)

  array = reshape(logspace(0.0_dp, 2.0_dp, 60), [6, 2, 5])
  call save_npy("array.npy", array)
end program demo_load

We can check whether the array is readable from Python and contains the expected data using numpy.load:

import numpy as np

farray = np.load("array.npy")
parray = np.logspace(0, 2, 60).reshape((6, 2, 5), order="F")

print(np.allclose(farray, parray))
# True

Note that arrays written in npy format by stdlib always will be in left-to-right memory layout (Fortran stride scheme, column major ordering).

Summary

Using the stdlib_io_npy module allows to

  • store data in a numpy compatible format

  • load data produced by numpy

  • safely round-trip data between Fortran and Python