【发布时间】:2021-09-28 20:19:27
【问题描述】:
TLDR:
- 如何根据文本文件的行列结构将 (Re, Im) 元组(按行和列排列)的纯文本文件读入 NumPy 复数数组?
- 如果可能的话,我如何对用 C++ 编写并读入 NumPy 数组的二进制文件执行相同的操作,如果可能的话直接传达行列结构?
详情:
我正在使用 C++ 代码运行物理模拟,并使用 Python 进行数据分析。我正在处理complex<double> 类型的数组(实际上是armadillo cx_mat 矩阵;我认为这与我的问题无关,但可能是)。
我需要将这种形状为Nt 行和Nx 列的数组写入一个文件,然后将其读入一个具有相同形状的复数双精度数的 numpy 数组。
最小的工作示例:我有以下 C++ 代码来输出数据,作为纯文本文件或二进制文件(当 Nt 和 Nx 变得非常大时,我需要使用二进制文件)。
//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();
我的问题:
-
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 列?
-
如果我改为写入二进制文件,如何将其读入类似的 NumPy 数组?另外,有没有办法编写二进制文件来编码行列结构? (我猜不是;如果不是,那么我的 NumPy 脚本中将提供
Nt和Nx) -
(尽管我的主要问题是 1. 和 2,但任何有关正确文件处理/错误检查的提示都将不胜感激。)
我确定这个问题之前已经回答过了,如果有人回答了,很抱歉。 (我已经搜索过,但是搜索这个问题会受到许多混淆因素的影响,例如“复杂”是“复杂”的同义词!)
附录: 我知道写入/读取二进制文件取决于平台。我将在同一台机器上写作和阅读,但我有兴趣学习如何解决这个问题,尽管这不是我的主要问题。同样,我没有包含任何文件错误处理,但想了解主要问题解决后的良好做法!
【问题讨论】:
-
未测试但你可以看看这个github.com/rogersce/cnpy/blob/master/cnpy.h - 这基本上可以让你从C++创建一个
.npy文件,然后你可以使用numpy.load加载你需要的所有检查。 -
另外,我不熟悉 Armadaillo,但 this 建议您可以将矩阵保存为 CSV 或 HDF5 格式,因此您可以使用
pandas或h5py从 numpy 加载它们或类似的东西。 -
谢谢霍尔特。我对 HDF5 一无所知,但它似乎是一个很好的解决方案。我想先学习如何在 NumPy 中处理原始二进制文件,但 HDF5 路线似乎很有用......
标签: python c++ numpy io binary-data