pack/unpack#
Mimics Fortran intrinsic pack and unpack functions
This module was written by Matthias Cuntz while at Department of Computational Hydrosystems, Helmholtz Centre for Environmental Research - UFZ, Leipzig, Germany, and continued while at Institut National de Recherche pour l’Agriculture, l’Alimentation et l’Environnement (INRAE), Nancy, France.
- copyright:
Copyright 2009-2023 Matthias Cuntz, see AUTHORS.rst for details.
- license:
MIT License, see LICENSE for details.
The following functions are provided
|
Mimics Fortran intrinsic pack (without optional vector) |
|
Mimics Fortran intrinsic unpack (without optional field) |
- History
Written Jul 2009 by Matthias Cuntz (mc (at) macu (dot) de)
Ported to Python 3, Feb 2013, Matthias Cuntz
Assert matching mask and array dimensions, Apr 2014, Matthias Cuntz
Code refactoring, Sep 2021, Matthias Cuntz
Port to pyjams, May 2023, Matthias Cuntz
Rename value keyword to fill_value as in numpy masked arrays, May 2023, Matthias Cuntz
Assert output type equals input type, May 2023, Matthias Cuntz
Use np.full instead of np.ones * fill_value, Jul 2023, Matthias Cuntz
- pack(array, mask)[source]#
Mimics Fortran intrinsic pack (without optional vector)
Packs the last dimensions of an arbitrary shaped array into a one dimensional array under a mask.
The mask can have any number of dimensions up to the array dimension.
- Parameters:
array (array) – ND-array to be packed
mask (array) – Boolean ND-array with number of dimensions <= array dimensions
- Returns:
array with reduced dimensions by number of mask dimensions minus one. Last dimension has only elements that correspond to elements of mask == True.
- Return type:
array
Notes
Result is undefined if all mask values are False.
Examples
Create some data for example an island in the middle of an ocean
>>> import numpy as np >>> island = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], ... [0., 0., 0., 1., 1., 1., 0., 0., 0., 0.], ... [0., 0., 0., 1., 1., 1., 0., 0., 0., 0.], ... [0., 0., 0., 1., 1., 1., 0., 0., 0., 0.], ... [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
Pack array to keep only the elements of the island
>>> mask = island == 1.0 >>> pisland = pack(island, mask) >>> print(pisland.size, pisland.shape) 9 (9,) >>> print(island.sum(), pisland.sum()) 9.0 9.0 >>> print(pisland) [1. 1. 1. 1. 1. 1. 1. 1. 1.]
Create data on the ocean and on the island for 2 time steps
>>> tshape = (2, *island.shape) >>> temp = np.arange(np.prod(tshape)).reshape(tshape)
Pack array to keep only the elements of the island
>>> ptemp = pack(temp, mask) >>> print(ptemp.size, ptemp.shape) 18 (2, 9) >>> print(ptemp) [[13 14 15 23 24 25 33 34 35] [63 64 65 73 74 75 83 84 85]]
- unpack(array, mask, fill_value=0)[source]#
Mimics Fortran intrinsic unpack (without optional field)
Unpacks the last dimension into several dimensions under a mask. The unpacked elements will be set to a user-defined fill_value.
The array can have any number of dimensions up to the mask dimensions.
- Parameters:
array (array) – ND-array to be unpacked
mask (array) – Boolean ND-array
fill_value (float, optional) – Value of the new elements (default: 0)
- Returns:
array having more dimensions by number of mask dimensions minus one. The new elements have the user-defined fill_value.
- Return type:
array
Notes
Result is undefined if all mask values are False.
Examples
Create some data for example an island in the middle of an ocean
>>> import numpy as np >>> island = np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], ... [0., 0., 0., 1., 1., 1., 0., 0., 0., 0.], ... [0., 0., 0., 1., 1., 1., 0., 0., 0., 0.], ... [0., 0., 0., 1., 1., 1., 0., 0., 0., 0.], ... [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]) >>> print(island.size, island.shape) 50 (5, 10)
Pack array to keep only the elements of the island
>>> mask = island == 1.0 >>> pisland = pack(island, mask) >>> print(pisland.size, pisland.shape) 9 (9,)
Unpack the ocean and island data again
>>> uisland = unpack(pisland, mask) >>> print(uisland.size, uisland.shape) 50 (5, 10) >>> print(np.all(uisland == island)) True
Unpack the ocean and island data, filling ocean with -9
>>> uisland = unpack(pisland, mask, -9) >>> print(uisland.size, uisland.shape) 50 (5, 10) >>> print(uisland) [[-9. -9. -9. -9. -9. -9. -9. -9. -9. -9.] [-9. -9. -9. 1. 1. 1. -9. -9. -9. -9.] [-9. -9. -9. 1. 1. 1. -9. -9. -9. -9.] [-9. -9. -9. 1. 1. 1. -9. -9. -9. -9.] [-9. -9. -9. -9. -9. -9. -9. -9. -9. -9.]]
Create data on the ocean and on the island for 2 time steps
>>> tshape = (2, *island.shape) >>> temp = np.arange(np.prod(tshape)).reshape(tshape)
>>> print(temp.size, temp.shape) 100 (2, 5, 10)
Pack array to keep only the elements of the island
>>> ptemp = pack(temp, mask) >>> print(ptemp.size, ptemp.shape) 18 (2, 9)
Unpack the ocean and island data. Note the ocean will have the fill_value -1 not its original data.
>>> utemp = unpack(ptemp, mask, fill_value=-1.) >>> print(utemp.size, utemp.shape) 100 (2, 5, 10) >>> ii = np.where(utemp != -1.) >>> print(np.all(utemp[ii] == temp[ii])) True