It looks like you might be interested in storing metadata in a permanent way along with your array. If so, HDF5 is a great option for use as a storage container.
For example, create an array and save it in an HDF file with some metadata using h5py :
import numpy as np import h5py some_data = np.random.random((100, 100)) with h5py.File('data.hdf', 'w') as outfile: dataset = outfile.create_dataset('my data', data=some_data) dataset.attrs['an arbitrary key'] = 'arbitrary values' dataset.attrs['foo'] = 10.2
Then we can read it:
import h5py with h5py.File('data.hdf', 'r') as infile: dataset = infile['my data'] some_data = dataset[...]
As already mentioned, if you are only involved in storing data + metadata in memory, the best option is a dict or a simple wrapper class. For instance:
class Container: def __init__(self, data, **kwargs): self.data = data self.metadata = kwargs
Of course, this will not behave like a numpy array directly, but it is usually a bad idea to subclass ndarrays . (You can, but itβs easy to do it wrong. You are almost always better at developing a class that stores the array as an attribute.)
Better yet, do all the operations you do with the same class in the example above. For instance:
import scipy.signal import numpy as np class SeismicCube(object): def __init__(self, data, bounds, metadata=None): self.data = data self.x0, self.x1, self.y0, self.y1, self.z0, self.z1= bounds self.bounds = bounds self.metadata = {} if metadata is None else metadata def inside(self, x, y, z): """Test if a point is inside the cube.""" inx = self.x0 >= x >= self.x1 iny = self.y0 >= y >= self.y1 inz = self.z0 >= z >= self.z1 return inx and iny and inz def inst_amp(self): """Calculate instantaneous amplitude and return a new SeismicCube.""" hilb = scipy.signal.hilbert(self.data, axis=2) data = np.hypot(hilb.real, hilb.imag) return type(self)(data, self.bounds, self.metadata)