【问题标题】:How do I save a 3D Python/NumPy array as a text file?如何将 3D Python/NumPy 数组保存为文本文件?
【发布时间】:2015-11-13 16:39:09
【问题描述】:

我必须启动大量计算,并且每次都必须保存一个 2D 文件文本,所以我想将结果“实时”存储为 3D 文本文件,每个切片对应一个计算结果。

第一次计算是可以的,但是当我进行第二次计算时,在“np.loadtxt”步骤中,数组维度变成了二维......所以我无法达到我的目标......而且我不能当我开始尺寸(...,...,1)时进行重塑

#MY FIRST RESULTS
test1 = open("C:/test.txt", "r")
test_r = np.genfromtxt(test, skip_header=1)
test_r = np.expand_dims(test_r, axis=2) #I create a new axis to save in 3D
test1.close()

#I test if the "Store" file to keep all my results is created.
try:
    Store= np.loadtxt('C:/Store.txt')
except:
    test=1

#If "Store" is not created, I do it or I concatenate in my file.
if test ==1:
    Store= test_r
    np.savetxt('C:/Store.txt', Store)
    test=2
else:
    Store = np.concatenate((Store,test_r), axis=2)
    np.savetxt('C:/Store.txt', Store)


#MY SECOND RESULTS
test2 = open("C:/test.txt", "r")
test_r = np.genfromtxt(test, skip_header=1)
test_r = np.expand_dims(test_r, axis=2)
test2.close()

#I launch the procedure again to "save" the results BUT DURING THE LOADTXT STEP THE ARRAY DIMENSIONS CHANGE TO BECOME A 2D ARRAY...
try:
    Store= np.loadtxt('C:/Store.txt')
except:
    test=1


if test ==1:
    Store= test_r
    np.savetxt('C:/Store.txt', Store)
    test=2
else:
    Store = np.concatenate((Store,test_r), axis=2)
    np.savetxt('C:/Store.txt', Store)

【问题讨论】:

  • 也许您更感兴趣的是使用可以轻松保存/加载任何 Python 对象的 Pickle 模块?
  • 我不知道,我会检查一下;)谢谢你有例子吗?我正在寻找那个
  • 根据您的用例,您可能能够摆脱与我最近在工作中所做的类似的事情。获取您的 numpy 数组,转换为普通的 python 列表并将其填充到 JSON 文件中。 JSON 是高度可移植的,您可以从那里读取您的数组。正如 Baruchel 提到的,有一些方法可以以二进制形式(例如 pickle)存储您的 numpy 数据。 Numpy 也为此内置了函数(列表顶部的前两个模块 docs.scipy.org/doc/numpy-1.10.0/reference/routines.io.html

标签: python arrays numpy text concatenation


【解决方案1】:

这是一个 cPickle 的例子:

import cPickle

# write to cPickle
cPickle.dump( thing_to_save, open( "filename.pkl", "wb" ) )

# read from cPickle
thing_to_save = cPickle.load( open( "filename.pkl", "rb" ) )

open() 函数的 "wb""rb" 参数很重要。 CPickle 以二进制格式写入对象,因此仅使用 "w""r" 是行不通的。

【讨论】:

    【解决方案2】:

    如果保存文件需要是“csv”样式的文本,您可以使用多个savetxtloadtxt。关键是知道这两者都可以 将打开的文件作为输入。

    编写示例:

    In [31]: A=np.arange(3*2*4).reshape(3,2,4)    
    In [32]: A    # normal display as 3 blocks of 2d array
    Out[32]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],
    
           [[ 8,  9, 10, 11],
            [12, 13, 14, 15]],
    
           [[16, 17, 18, 19],
            [20, 21, 22, 23]]])
    
    In [36]: for a in A:print a, '\n'   # or iterate on the 1st dimension
    [[0 1 2 3]
     [4 5 6 7]] 
    
    [[ 8  9 10 11]
     [12 13 14 15]] 
    
    [[16 17 18 19]
     [20 21 22 23]] 
    

    按照该示例,我可以对文件进行迭代,对每个子数组使用 savetxt

    In [37]: with open('3dcsv.txt','wb') as f:
        for a in A:
            np.savetxt(f, a, fmt='%10d')
            f.write('\n')
       ....:         
    

    用系统cat确认文件写入(通过ipython):

    In [38]: cat 3dcsv.txt
             0          1          2          3
             4          5          6          7
    
             8          9         10         11
            12         13         14         15
    
            16         17         18         19
            20         21         22         23
    

    对于简单的读取,loadtxt 显然会忽略空行,返回一个 6 x 4 数组。所以我知道它应该是(2,3,4) 我可以轻松地重塑结果。

    In [39]: np.loadtxt('3dcsv.txt')
    Out[39]: 
    array([[  0.,   1.,   2.,   3.],
           [  4.,   5.,   6.,   7.],
           [  8.,   9.,  10.,  11.],
           [ 12.,  13.,  14.,  15.],
           [ 16.,  17.,  18.,  19.],
           [ 20.,  21.,  22.,  23.]])
    

    经过一些调试,我得到了这个多重 loadtxt 工作。 loadtxt(和genfromtxt)适用于行列表。

    In [53]: A1=[]     # list to collect blocks
    
    In [54]: with open('3dcsv.txt') as f:
        lines = []     # list to collect lines
        while 1:
            aline = f.readline()
            if aline.strip():
                lines.append(aline)     # nonempty line
            else:              # empty line
                if len(lines)==0: break
                A1.append(np.loadtxt(lines, dtype=int))
                lines = []
       ....:             
    
    In [55]: A1 = np.array(A1)
    
    In [56]: A1
    Out[56]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],
    
           [[ 8,  9, 10, 11],
            [12, 13, 14, 15]],
    
           [[16, 17, 18, 19],
            [20, 21, 22, 23]]])
    

    这可能不是最强大的保存/加载配对,但它提供了一个框架来构建更好的东西。

    但如果它不需要是文本,那么 pickle 就可以了,原生 numpy 'save/load' 也是如此

    In [57]: np.save('3dsave.npy',A)
    
    In [58]: np.load('3dsave.npy')
    Out[58]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],
    
           [[ 8,  9, 10, 11],
            [12, 13, 14, 15]],
    
           [[16, 17, 18, 19],
            [20, 21, 22, 23]]])
    

    【讨论】:

    • 使用 Python 3.7,我得到:“f.write('\n') TypeError: a bytes-like object is required, not 'str'”
    • ...使用 open(...,'w') 代替 open(...,'wb') 解决了这个问题
    猜你喜欢
    • 2018-12-15
    • 1970-01-01
    • 2012-06-21
    • 2016-06-21
    • 2019-01-22
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多