【问题标题】:write complex<double>'s to plain text/binary file in C++, and read them into a NumPy array在 C++ 中将 complex<double> 写入纯文本/二进制文件,并将它们读入 NumPy 数组
【发布时间】:2021-09-28 20:19:27
【问题描述】:

TLDR:

  1. 如何根据文本文件的行列结构将 (Re, Im) 元组(按行和列排列)的纯文本文件读入 NumPy 复数数组?
  2. 如果可能的话,我如何对用 C++ 编写并读入 NumPy 数组的二进制文件执行相同的操作,如果可能的话直接传达行列结构?

详情:

我正在使用 C++ 代码运行物理模拟,并使用 Python 进行数据分析。我正在处理complex&lt;double&gt; 类型的数组(实际上是armadillo cx_mat 矩阵;我认为这与我的问题无关,但可能是)。

我需要将这种形状为Nt 行和Nx 列的数组写入一个文件,然后将其读入一个具有相同形状的复数双精度数的 numpy 数组。

最小的工作示例:我有以下 C++ 代码来输出数据,作为纯文本文件或二进制文件(当 NtNx 变得非常大时,我需要使用二进制文件)。

  //data is in my_cx_double_arr
  
  //write data to plain txt file                                                                                                                                                              
  ofstream txt_fout_stream("txt_output.txt" , ios::out | ios::app);
  txt_fout_stream << scientific;
  txt_fout_stream.precision(12);
  for(int i=0; i<Nt; i++){
    for(int j=0; j<Nx; j++){
      txt_fout_stream << my_cx_double_arr(i,j) << " ";
    }
    txt_fout_stream << endl;
  }
  txt_fout_stream.close();

  //write data to binary file                                                                                                                                                                 
  ofstream bin_fout_stream("bin_output.bin", ios::out | ios::app | ios::binary);
  for(int i=0; i<Nt; i++){
    for(int j=0; j<Nx; j++){
      bin_fout_stream.write(reinterpret_cast<char*>( &my_cx_double_arr(i,j) ) , sizeof(complex<double>));
      }
    }
  bin_fout_stream.close();

我的问题:

  1. txt_output.txt 被格式化为正确形状的元组数组,例如:
(5.610842645053e-02,-5.700807222085e-01) (-1.198577806951e+00,9.814201723115e-01) 
(5.016283876502e-01,-1.965153563607e-01) (-2.629706723344e-01,1.228331874675e+00) 
(-2.431860857327e-01,-3.638485210072e-01) (-3.030812460688e-01,7.194149378419e-01) 

如何将其读入一个 NumPy 复数数组,每个元组读入 z=(Re,Im),并且该数组具有与文本文件中相同的 Nt 行和 Nx 列?

  1. 如果我改为写入二进制文件,如何将其读入类似的 NumPy 数组?另外,有没有办法编写二进制文件来编码行列结构? (我猜不是;如果不是,那么我的 NumPy 脚本中将提供 NtNx

  2. (尽管我的主要问题是 1. 和 2,但任何有关正确文件处理/错误检查的提示都将不胜感激。)

我确定这个问题之前已经回答过了,如果有人回答了,很抱歉。 (我已经搜索过,但是搜索这个问题会受到许多混淆因素的影响,例如“复杂”是“复杂”的同义词!)

附录: 我知道写入/读取二进制文件取决于平台。我将在同一台机器上写作和阅读,但我有兴趣学习如何解决这个问题,尽管这不是我的主要问题。同样,我没有包含任何文件错误处理,但想了解主要问题解决后的良好做法!

【问题讨论】:

  • 未测试但你可以看看这个github.com/rogersce/cnpy/blob/master/cnpy.h - 这基本上可以让你从C++创建一个.npy文件,然后你可以使用numpy.load加载你需要的所有检查。
  • 另外,我不熟悉 Armadaillo,但 this 建议您可以将矩阵保存为 CSV 或 HDF5 格式,因此您可以使用 pandash5py 从 numpy 加载它们或类似的东西。
  • 谢谢霍尔特。我对 HDF5 一无所知,但它似乎是一个很好的解决方案。我想先学习如何在 NumPy 中处理原始二进制文件,但 HDF5 路线似乎很有用......

标签: python c++ numpy io binary-data


【解决方案1】:

好的,看起来 2. 的答案非常简单。

import numpy as np

fname = open('bin_output.bin')
data_in = np.fromfile( fname, dtype=np.complex_, count =-1)
fname.close()
data_reshaped = np.reshape(data_in, (Nt,Nx))

data_reshaped 中的数字与人类可读文件 txt_output.txt 中的数字完全匹配。

然而这似乎不是 1 的答案。应用于txt_output.txt 的相同方法给出了一个数组data_in,它具有完全不同的形状,并且具有完全不同的数字(具有完全不同的数量级) 比文件txt_output.txt 中的实际内容。

奇怪!

【讨论】:

    猜你喜欢
    • 2012-11-02
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 2012-10-13
    • 2021-03-17
    • 2018-08-16
    相关资源
    最近更新 更多