问题
I am trying to save an array of data along with header information. Currently, I am using numpy.savez() to save the header information (a dictionary) in one array, and the data in another.
data = [[1,2,3],[4,5,6]]
header = {'TIME': time, 'POSITION': position}
np.savez(filename, header=header, data=data)
When I try to load and read the file, however, I can't index the header dictionary.
arrays = np.load(filename)
header = arrays('header')
data = arrays('data')
print header['TIME']
I get the following error:
ValueError: field named TIME not found.
Before saving, the header is type 'dict'. After saving/loading, it is type 'numpy.ndarray'. Can I convert it back to a dictionary? Or is there a better way to achieve the same result?
回答1:
np.savez saves only numpy arrays. If you give it a dict, it will call np.array(yourdict) before saving it. So this is why you see something like type(arrays['header']) as np.ndarray:
arrays = np.load(filename)
h = arrays['header'] # square brackets!!
>>> h
array({'POSITION': (23, 54), 'TIME': 23.5}, dtype=object)
You'll notice if you look at it though, that it is a 0-dimensional, single-item array, with one dict inside:
>>> h.shape
()
>>> h.dtype
dtype('O') # the 'object' dtype, since it's storing a dict, not numbers.
so you could work around by doing this:
h = arrays['header'][()]
The mysterious indexing gets the one value out of a 0d array:
>>> h
{'POSITION': (23, 54), 'TIME': 23.5}
回答2:
As in @askewchan's comment, why not np.savez( "tmp.npz", data=data, **d ) ?
import numpy as np
data = np.arange( 3 )
time = 23.5
position = [[23, 54], None]
d = dict( TIME=time, POSITION=position )
np.savez( "tmp.npz", data=data, **d )
d = np.load( "tmp.npz" )
for key, val in sorted( d.items() ):
print key, type(val), val # note d.TIME is a 0-d array
This is not your question at all, but the following little
class Bag is nice,
and you can bag.<tab> in IPython:
#...............................................................................
class Bag( dict ):
""" a dict with d.key short for d["key"]
d = Bag( k=v ... / **dict / dict.items() / [(k,v) ...] ) just like dict
"""
# aka Dotdict
def __init__(self, *args, **kwargs):
dict.__init__( self, *args, **kwargs )
self.__dict__ = self
def __getnewargs__(self): # for cPickle.dump( d, file, protocol=-1)
return tuple(self)
d = Bag( np.load( "tmp.npz" ))
if d.TIME > 0:
print "time %g position %s" % (d.TIME, d.POSITION)
来源:https://stackoverflow.com/questions/22315595/saving-dictionary-of-header-information-using-numpy-savez