mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
166 lines
4.7 KiB
Python
166 lines
4.7 KiB
Python
from org.meteoinfo.ndarray.io.npy import Npy, Npz
|
|
from ..core._ndarray import NDArray
|
|
|
|
__all__ = ['load', 'save', 'savez']
|
|
|
|
|
|
class NpzFile:
|
|
"""
|
|
NpzFile(fid)
|
|
|
|
A dictionary-like object with lazy-loading of files in the zipped
|
|
archive provided on construction.
|
|
|
|
`NpzFile` is used to load files in the NumPy ``.npz`` data archive
|
|
format. It assumes that files in the archive have a ``.npy`` extension,
|
|
other files are ignored.
|
|
|
|
Attributes
|
|
----------
|
|
files : list of str
|
|
List of all files in the archive with a ``.npy`` extension.
|
|
zip_file : ZipFile instance
|
|
The ZipFile object initialized with the zipped archive.
|
|
"""
|
|
zip_file = None
|
|
_MAX_REPR_ARRAY_COUNT = 5
|
|
|
|
def __init__(self, file):
|
|
self.filename = file
|
|
self.zip_file = Npz.open(file)
|
|
self._files = list(Npz.entries(self.zip_file))
|
|
self.files = []
|
|
for x in self._files:
|
|
if x.endswith('.npy'):
|
|
self.files.append(x[:-4])
|
|
else:
|
|
self.files.append(x)
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
self.close()
|
|
|
|
def close(self):
|
|
"""
|
|
Close the zip file.
|
|
"""
|
|
if self.zip_file is not None:
|
|
self.zip_file.close()
|
|
self.zip_file = None
|
|
|
|
def __del__(self):
|
|
self.close()
|
|
|
|
# Implement the Mapping ABC
|
|
def __iter__(self):
|
|
return iter(self.files)
|
|
|
|
def __len__(self):
|
|
return len(self.files)
|
|
|
|
def __contains__(self, key):
|
|
return (key in self._files or key in self.files)
|
|
|
|
def __repr__(self):
|
|
# Get the name of arrays
|
|
array_names = ', '.join(self.files[:self._MAX_REPR_ARRAY_COUNT])
|
|
if len(self.files) > self._MAX_REPR_ARRAY_COUNT:
|
|
array_names += "..."
|
|
return "NpzFile {} with keys: {}".format(self.filename, array_names)
|
|
|
|
def __getitem__(self, key):
|
|
member = False
|
|
if key in self._files:
|
|
member = True
|
|
elif key in self.files:
|
|
member = True
|
|
key += '.npy'
|
|
if member:
|
|
a = Npz.load(self.zip_file, key)
|
|
return NDArray(a)
|
|
else:
|
|
raise KeyError("{} is not a file in the archive".format(key))
|
|
|
|
|
|
def load(file):
|
|
"""
|
|
Load arrays from `npy` or `npz` data file.
|
|
|
|
:param file: (*str*) Data file path.
|
|
|
|
:return: Array or diction of arrays.
|
|
"""
|
|
# Code to distinguish from NumPy binary files and pickles.
|
|
MAGIC_PREFIX = b'\x93NUMPY'
|
|
_ZIP_PREFIX = b'PK\x03\x04'
|
|
_ZIP_SUFFIX = b'PK\x05\x06' # empty zip files start with this
|
|
|
|
fid = open(file, 'rb')
|
|
N = len(MAGIC_PREFIX)
|
|
magic = fid.read(N)
|
|
fid.close()
|
|
if not magic:
|
|
raise EOFError("No data left in file")
|
|
|
|
if magic.startswith(_ZIP_PREFIX) or magic.startswith(_ZIP_SUFFIX):
|
|
return NpzFile(file)
|
|
else:
|
|
a = Npy.load(file)
|
|
return NDArray(a)
|
|
|
|
def save(file, arr):
|
|
"""
|
|
Save an array to a binary file in NumPy .npy format.
|
|
|
|
:param file: (*str*) Npy file path.
|
|
:param arr: (*array*) Array data to be saved.
|
|
"""
|
|
if not file.endswith('.npy'):
|
|
file = file + '.npy'
|
|
|
|
Npy.save(file, arr._array)
|
|
|
|
def savez(file, *args, **kwds):
|
|
"""
|
|
Save several arrays into a single file in uncompressed ``.npz`` format.
|
|
|
|
Provide arrays as keyword arguments to store them under the
|
|
corresponding name in the output file: ``savez(fn, x=x, y=y)``.
|
|
|
|
If arrays are specified as positional arguments, i.e., ``savez(fn,
|
|
x, y)``, their names will be `arr_0`, `arr_1`, etc.
|
|
|
|
Parameters
|
|
----------
|
|
file : str
|
|
The filename (string) where the data will be saved. If file is a string or a Path, the
|
|
``.npz`` extension will be appended to the filename if it is not
|
|
already there.
|
|
args : Arguments, optional
|
|
Arrays to save to the file. Please use keyword arguments (see
|
|
`kwds` below) to assign names to arrays. Arrays specified as
|
|
args will be named "arr_0", "arr_1", and so on.
|
|
kwds : Keyword arguments, optional
|
|
Arrays to save to the file. Each array will be saved to the
|
|
output file with its corresponding keyword name.
|
|
"""
|
|
if not file.endswith('.npz'):
|
|
file = file + '.npz'
|
|
|
|
namedict = kwds
|
|
for i, val in enumerate(args):
|
|
key = 'arr_{}'.format(i)
|
|
if key in namedict.keys():
|
|
raise ValueError(
|
|
"Cannot use un-named variables and keyword {}".format(key))
|
|
namedict[key] = val
|
|
|
|
outstream = Npz.create(file)
|
|
for key, val in namedict.items():
|
|
fname = key + '.npy'
|
|
Npz.write(outstream, key, val._array)
|
|
|
|
outstream.close()
|