2

Numpy allows to export several arrays in a single npz file which can be loaded then, using for instance:

infile = "somefile.npz"
inData = np.load( infile)
print( inData.files) #will list all the arrays importable from the file

I am interested in function that could load all the data and conserve the naming before exportation in one call.

I can do it `inline' by:

infile = "somefile.npz"
inData = np.load( infile)
for varName in inData.files:
    exec(varName + " = inData[\"" + varName + "\"]")

which seems to work. But as I would like to make use of this in multiple places, it does not seem to work when moved into a function:

def importEverything( infile):
    #imports everything inside the npz input file and keeps the variable in the global namespace

It seems that the scope of variables cannot extend from this function's local scope.

It seems that I am misunderstanding something about Python here. Is it possible to do? Is it non advisable?

1
  • 1
    Downloading the contents of a dictionary to globals() is discouraged. Commented Jan 31, 2017 at 17:00

2 Answers 2

1

The following should work by using the globals function. In the docs it states that the scope is the defining module not the calling. So the function needs to be defined in the same module it is called from.

import numpy as np

def import_npz(npz_file):
    Data = np.load(npz_file)
    for varName in Data:
        globals()[varName] = Data[varName]

import_npz('test.npz')

If you want to put your function in a module try this:

from import_test import import_npz
import_npz('test.npz', globals())

import_test.py

import numpy as np
def import_npz(npz_file, namespace):
    Data = np.load(npz_file)
    for varName in Data:
        namespace[varName] = Data[varName]
Sign up to request clarification or add additional context in comments.

Comments

1

This is actually not a problem of variable scope. Actually your second code block does not work. If you print out the command you are executing, you get:

arr_0 = inData[arr_0]

This is why you get the error: NameError: name 'arr_0' is not defined, because arr_0 is not defined, yet you are trying to index inData with arr_0. What you want to do is actually:

arr_0 = inData['arr_0']

To solve this problem, just add single quotation marks around the second varName so it becomes a string and not a variable name. Try this:

infile = "somefile.npz"
inData = np.load( infile)
for varName in inData.files:
    exec(varName + " = inData['" + varName + "']")

and everything works. Now you can define your function:

def importEverything(infile):
    for varName in inData.files:
        exec(varName + " = inData['" + varName + "']")

Input:

import numpy as np


x = np.array([1,2,3])
y = np.array([[1,2], [3,4]])
np.savez('somefile', x, y)

importEverything('somefile.npz')
print(arr_0)
print(arr_1)

Output:

[1 2 3]
[[1 2]
 [3 4]]

2 Comments

Indeed, I had forgotten the quote marks. Thanks for the input.
If my answer is correct, please select it to be the correct answer, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.