rpb
rpb

Reputation: 3299

Call array with keyword argument from npz in Numpy

Given multiple array which saved as npz format as below

from numpy import load
import numpy as np
names=['t1','t2','t3']
arr_name = np.array(names)
all_arr=[]
for idx,fname in enumerate(names):
    all_arr.append(np.arange(10))

np.savez('data.npz', dict(zip(names,all_arr)),names=arr_name)

Re-load it with keyword argument as below

dict_data = load('data.npz')
data = dict_data['t1']

Return an error

KeyError: 't1 is not a file in the archive'

May I know what is the problem here.

Upvotes: 0

Views: 390

Answers (1)

hpaulj
hpaulj

Reputation: 231500

In [165]: names=['t1','t2','t3']
     ...: arr_name = np.array(names)
     ...: all_arr=[]
     ...: for idx,fname in enumerate(names):
     ...:     all_arr.append(np.arange(10))
     ...: 
     ...: np.savez('data.npz', dict(zip(names,all_arr)),names=arr_name)
     ...: 

Here's what you saved:

In [166]: data = np.load('data.npz')
In [168]: list(data.keys())
Out[168]: ['names', 'arr_0']

In [169]: data['names']
Out[169]: array(['t1', 't2', 't3'], dtype='<U2')
In [170]: data['arr_0']
Traceback (most recent call last):
  File "<ipython-input-170-0247585f6b05>", line 1, in <module>
    data['arr_0']
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/npyio.py", line 254, in __getitem__
    return format.read_array(bytes,
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/format.py", line 743, in read_array
    raise ValueError("Object arrays cannot be loaded when "
ValueError: Object arrays cannot be loaded when allow_pickle=False

checking the arguments to the savez:

In [171]: arr_name
Out[171]: array(['t1', 't2', 't3'], dtype='<U2')
In [172]: dict(zip(names, all_arr))
Out[172]: 
{'t1': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
 't2': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
 't3': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])}

Using ** to expand that dict into keyword arguments, does save things as you want:

In [174]: np.savez('test.npz', **_)
In [175]: data = np.load('test.npz')
In [176]: list(data.keys())
Out[176]: ['t1', 't2', 't3']
In [177]: data['t1']
Out[177]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

that's equivalent to using:

In [179]: np.savez('test.npz', t1=all_arr[0])
In [180]: data = np.load('test.npz')
In [181]: list(data.keys())
Out[181]: ['t1']
In [182]: data['t1']
Out[182]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

I don't see anything the savez docs that corresponds to a names parameter (such as what you use).

To load the original file, I have to load with `

In [189]: data = np.load('data.npz', allow_pickle=True)
In [193]: data['arr_0'].item()['t1']
Out[193]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

That is the dict is "buried" in a single item object dtype array.

Upvotes: 1

Related Questions