【问题标题】:numpy savetxt: save a matrix as rownumpy savetxt:将矩阵保存为行
【发布时间】:2014-03-04 13:36:14
【问题描述】:

我正在使用 numpy savetxt() 将矩阵的元素保存为单行文件(我需要按顺序打印很多)。这是我找到的方法:

import numpy as np

mat = np.array([[1,2,3],
                [4,5,6],
                [7,8,9]])

with open('myfile.dat','a') as handle:
    np.savetxt(handle, mat.reshape(1,mat.size), fmt='%+.8e')
handle.close()

有2个问题:

1) savetxt() 是最佳选择吗?我需要打印 1e5 到 1e7 这些东西......而且我不希望 i/o 成为实际计算的瓶颈。我猜在速度方面,每次迭代都重新打开文件是一个糟糕的计划。

2) 理想情况下,我会打印一些上下文数据来开始每一行,所以我的输出可能如下所示:

(N foo mat):

...
6 -2.309 +1.000 +2.000 ...
7 -4.273 +1.000 +2.000 ...
8 -3.664 +1.000 +2.000 ...
...

我可以使用np.append() 执行此操作,但是第一个数字不会打印为 INT。这种事情可以直接在savetxt() 中实现吗?还是我需要一个类似 C 的 fprintf() 反正?

【问题讨论】:

    标签: python python-3.x numpy matrix


    【解决方案1】:

    Pandas 有一个很好的to_csv 方法:

    import pandas as pd
    import numpy as np
    
    mat = np.array([[1,2,3],
                    [4,5,6],
                    [7,8,9]])
    df = pd.DataFrame(data=mat.astype(np.float))
    df.to_csv('myfile.dat', sep=' ', float_format='%+.8e', header=False)
    

    默认情况下,它会添加索引 (index=True),但如果您想要不同的上下文数据,您可以将其添加到数据框中并设置 index=False

    $ cat myfile.dat 
    0 +1.00000000e+00 +2.00000000e+00 +3.00000000e+00
    1 +4.00000000e+00 +5.00000000e+00 +6.00000000e+00
    2 +7.00000000e+00 +8.00000000e+00 +9.00000000e+00
    

    【讨论】:

    • 看起来to_csv 不能附加到现有文件上。这意味着我必须在 RAM 中携带一个潜在的巨大数据帧并在最后将其转储到文件中。我想我可以试验一下这个的可行性......
    • 我明白了。现在我对savetxt 解决方案很满意。将矩阵复制到 DataFrame 中只是为了打印它似乎是一种排序或迂回。
    【解决方案2】:

    好的。我打印为数组的原始代码仅在您想打印一次时才有效。 mat.reshape() 方法不仅返回它改变 mmat 本身的重塑矩阵。这意味着下次循环时,任何linalg 例程都会失败。

    为避免这种情况,我们需要重塑 copy()mat。为了清楚起见,我还添加了一个 tmp 变量。

    import numpy as np
    
    mat = np.array([[1,2,3],
                    [4,5,6],
                    [7,8,9]]) # initialize mat to see format
    
    handle = open('myfile.dat', 'ab')
    for n in range(N):
        # perform linalg calculations on mat ...
        meta = foo # based on current mat
    
        tmp = np.hstack( ([[n]], [[meta]], (mat.copy()).reshape(1,mat.size)) )
        np.savetxt(handle, tmp, fmt='%+.8e')
    
    handle.close()
    

    在这种情况下,这将获取上下文数据 nmeta。我可以忍受n 被保存为float

    我做了一些基准测试来检查 I/O 成本。我为循环设置 N=100,000,平均运行 6 次:

    • 无 i/o,仅计算:9.1 秒
    • 如上编码:17.2 秒
    • 打开“myfile.dat”以追加每次迭代:30.6 秒

    因此 i/o 使运行时间加倍,并且正如预期的那样,不断打开和关闭文件是一个糟糕的计划。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2014-04-28
      • 2010-12-14
      • 2021-10-05
      • 2015-09-04
      • 1970-01-01
      • 2017-03-04
      相关资源
      最近更新 更多