2014-03-28 76 views
8

從循環中我得到一個數組。我想將這個數組保存在tempfile中。 問題是np.savez只保存循環中的最後一個數組。我想我明白爲什麼會發生這種情況,但不知道如何做得更好。如何在循環中使用`numpy.savez`來保存多個數組?

爲了解決我的問題,我打算在mode=a+b中打開臨時文件,目標是追加循環中的新數組。但這不起作用。

到目前爲止我的代碼:

tmp = TemporaryFile(mode="a+b")  
for i in range(10): 
    array = getarray[i] #demo purpose 
    np.savez(tmp,array) 
tmp.seek(0) 

然後使用臨時文件讀取數組:

tmp_read = np.load(tmp) 
print tmp_read.files 
[OUTPUT]: ['arr_0'] 

但我想在臨時文件10個陣列。有任何想法嗎?
謝謝

+0

如果數組太大而無法在內存中完全分配,並且您想堅持使用for循環,請對每個數組使用一個文件。我不認爲你可以在追加模式下使用'.npz'文件。 – gg349

+0

'.npz'是一個標準的zip壓縮文件。這意味着'.npy'文件可以通過任何歸檔工具添加或刪除(從Python或shell或窗口中)。玩起來很容易。 – hpaulj

回答

8

您可以使用*args參數將多個數組僅保存在一個臨時文件中。

np.savez(tmp, *getarray[:10]) 

或:

np.savez(tmp, *[getarray[0], getarray[1], getarray[8]]) 
+1

不能將語法縮短爲僅僅* getarray [:10]'?如果'getarray'已經是一個列表,那麼列表理解是有點不必要的。 –

+0

@imaluengo你是對的,這個例子會更好地顯示許多數組可以被保存,例如,通過做'[getarray [0],getarray [2],getarray [3]]' –

+1

是的!我明白了一點,我只是認爲值得一提的是'myarraylist'可以用來縮短語法,以防列表已經創建好:) –

3

對不起,我的英語進步。

因爲函數savez打開文件,寫入所有變量,然後關閉文件,數據在被調用時被覆蓋。

savez很簡單。你可以找到代碼https://github.com/numpy/numpy/blob/master/numpy/lib/npyio.py

如何實現「your_own_savez」,然後使用下面的代碼。

tmp = TemporaryFile() 
f = my_savez(tmp)  
for i in range(10): 
    array = getarray[i] #demo purpose 
    f.savez(array) 
f.close() 

tmp.seek(0) 
tmp_read = np.load(tmp) 
print tmp_read.files 

這是我的快速和骯髒的代碼。

import numpy as np 
import tempfile 

class my_savez(object): 
    def __init__(self, file): 
     # Import is postponed to here since zipfile depends on gzip, an optional 
     # component of the so-called standard library. 
     import zipfile 
     # Import deferred for startup time improvement 
     import tempfile 
     import os 

     if isinstance(file, basestring): 
      if not file.endswith('.npz'): 
       file = file + '.npz' 

     compression = zipfile.ZIP_STORED 

     zip = self.zipfile_factory(file, mode="w", compression=compression) 

     # Stage arrays in a temporary file on disk, before writing to zip. 
     fd, tmpfile = tempfile.mkstemp(suffix='-numpy.npy') 
     os.close(fd) 

     self.tmpfile = tmpfile 
     self.zip = zip 
     self.i = 0 

    def zipfile_factory(self, *args, **kwargs): 
     import zipfile 
     import sys 
     if sys.version_info >= (2, 5): 
      kwargs['allowZip64'] = True 
     return zipfile.ZipFile(*args, **kwargs) 

    def savez(self, *args, **kwds): 
     import os 
     import numpy.lib.format as format 

     namedict = kwds 
     for val in args: 
      key = 'arr_%d' % self.i 
      if key in namedict.keys(): 
       raise ValueError("Cannot use un-named variables and keyword %s" % key) 
      namedict[key] = val 
      self.i += 1 

     try: 
      for key, val in namedict.iteritems(): 
       fname = key + '.npy' 
       fid = open(self.tmpfile, 'wb') 
       try: 
        format.write_array(fid, np.asanyarray(val)) 
        fid.close() 
        fid = None 
        self.zip.write(self.tmpfile, arcname=fname) 
       finally: 
        if fid: 
         fid.close() 
     finally: 
      os.remove(self.tmpfile) 

    def close(self): 
     self.zip.close() 

tmp = tempfile.TemporaryFile() 
f = my_savez(tmp) 
for i in range(10): 
    array = np.zeros(10) 
    f.savez(array) 
f.close() 

tmp.seek(0) 

tmp_read = np.load(tmp) 
print tmp_read.files 
for k, v in tmp_read.iteritems(): 
    print k, v 
2

我不是一個有經驗的程序員,但是這是我做的(以防萬一它可以幫助一個人在未來)的方式。此外,它是我在這裏發佈的第一次,所以我道歉,如果我不按某種標準的;)

創建NPZ文件:

import numpy as np 

tmp = file("C:\\Windows\\Temp\\temp_npz.npz",'wb') 

# some variables 
a= [23,4,67,7] 
b= ['w','ww','wwww'] 
c= np.ones((2,6)) 

# a lit containing the name of your variables 
var_list=['a','b','c'] 

# save the npz file with the variables you selected 
str_exec_save = "np.savez(tmp,"  
for i in range(len(var_list)):  
    str_exec_save += "%s = %s," % (var_list[i],var_list[i]) 
str_exec_save += ")" 
exec(str_exec_save) 

tmp.close 

與原來的加載變量名稱:

import numpy as np 
import tempfile 

tmp = open("C:\\Windows\\Temp\\temp_npz.npz",'rb') 

# loading of the saved variables 
var_load = np.load(tmp) 

# getting the name of the variables 
files = var_load.files 

# loading then with their original names 
for i in range(len(files)): 
    exec("%s = var_load['%s']" % (files[i],files[i])) 

唯一的區別是變量將變成numpy變量。

相關問題