使用不同的扫描方向导入二进制数据

时间:2014-04-03 07:33:13

标签: python import binary-data direction

我有一个C代码可以计算2D空间的某些物理变量(例如x-velocity" u"和y-velocity" v",其中" u&# 34;和" v"是空间坐标的函数" x"和" y":" u = u(x,y)"和" v = v(x,y)")。

然后将结果导出为二进制文件(数据类型为" double")。然后我用python脚本打开数据文件,这样我就可以进行一些后期处理并使用matplotlib绘制数据。

如您所知,有两种扫描2D阵列的方法:

  • 首先选择一行并扫描行内的每个单元格
  • 或者您完全相反:首先选择一列并扫描列中的每个单元格

显然,我遇到的问题是,我的C代码保存数组的方向与我的python脚本读取数组的方向不同。

C文件使用fwrite()函数,我希望保持原样。

fwrite(vect , sizeof(double), nbcols*nbrows, file);

python文件使用struct模块解压缩数组:

unpackFormat = '%dd' % nDim
zx = np.array([struct.unpack(unpackFormat,f.read())]).reshape(v.N,v.M)

在我的特定情况下,我可以找到一种解决方法,但它很难看,可能无法在所有情况下使用。所以这就是我的问题:是否有任何方法可以解压缩数组,使其以默认方向扫描?

我的数组只包含双打,如果我理解正确,array.fromfile可以处理这种情况,所以如果您碰巧知道array.fromfile的答案,请随时分享!


关于我的具体案例的额外信息

在下文中,我提供了更多针对我的问题的详细信息,尽管我刚刚表达的内容应该足以让您了解我的问题。注意:下面会有一些numpy + matplolib,尽管我的问题与结构模块有关,而不是与matplotlib相关。

我想要做的是速度场的颤动图。这意味着我想绘制一个"箭头字段"如[here] [1]中,点(x,y)上的箭头对应于矢量(u(x,y),v(x,y))。这是我的剧本中有趣的部分:

# gen x,y coordinates
y, x = np.mgrid[0:1:complex(0,v.N),
                0:1:complex(0,v.M)]

# load data for the x-direction
f = open(filePathX, 'rb')
unpackFormat = '%dd' % nDim
zx = np.array([struct.unpack(unpackFormat,f.read())]).reshape(v.N,v.M)
f.close()

# load data for the y-direction
f = open(filePathY, 'rb')
unpackFormat = '%dd' % nDim
zy = np.array([struct.unpack(unpackFormat,f.read())]).reshape(v.N,v.M)
f.close()

# plotting
plt.quiver(x[::10,::10], y[::10,::10], zx[::10,::10], zy[::10,::10])

使用此脚本,绘图没有很好地绘制:就好像输出向量zx和zy的x和y坐标已被交换。换句话说,每个箭头对应于向量(v,u)而不是向量(u,v)。我将此归因于struct.unpack在另一个方向读取数组,这是我希望的那个。

在我的特殊情况下,我正在跳跃一个旋转的速度场,而是箭头指向X和Y轴向内或向外。

重要的精度:Matplotlib不允许我交换x和y数组。

解决方法是执行以下操作:

plt.quiver(x[::10,::10], y[::10,::10], -zy[::10,::10], -zx[::10,::10])

但我不喜欢这种做事方式,所以我希望你能提出一个更好的方法来解决我的问题

提前致谢!

1 个答案:

答案 0 :(得分:0)

愚蠢的我刚刚找到答案:

使用:

zx = np.array([struct.unpack(unpackFormat,f.read())]).reshape(v.N,v.M,order='F')

而不是:

zx = np.array([struct.unpack(unpackFormat,f.read())]).reshape(v.N,v.M)

这样做会改变数组的读取方式。实际上问题并非来自struct.unpack,而是来自np.array.reshape。后者有一个可选参数来设置扫描方向。在这里,我为“fortran”扫描约定选择了F选项(即使我的数据是由C代码保存的),而不是默认的C值(对于C扫描约定)。

我想我必须从我的C代码开始以奇怪的方式存储数组,因此我需要以非常规的方式阅读它们。仍然困扰我,但至少它的脚本看起来很干净。