我正在尝试读取流量数据并将数据分发到网格文件中以进行最终绘图。我有用于处理的MATLAB代码,它可以成功运行。我需要将此代码转移到Python中,但是我是一个初学者。调试时总是崩溃,谁能告诉我我在做什么错?提前致谢!
数据文件(总计约100mb):
https://www.dropbox.com/sh/3gtsmatq56pm0gc/AADUnNLjdrELjvdUy4wtDiiBa?dl=0
MATLAB代码
%% Read Grid grid file is used as a guide for the positon where data is put
fid = fopen('FLOW_phys_GRID_1.xyz', 'r');
a = fread(fid, 3, 'int');
Nx = a(1); % number of points in x direction
Ny = a(2); % number of points in y direction
Nz = a(3); % numebr of points in z direction
xx = fread(fid, Nx*Ny*Nz, 'float');
yy = fread(fid, Nx*Ny*Nz, 'float');
xx = reshape(xx, [Nx, Ny]);
yy = reshape(yy, [Nx, Ny]);
fclose(fid);
x = squeeze(xx(:,1));
y = squeeze(yy(1,:));
%% Read Data
fid = fopen('FLOW_phys.raw', 'r'); %flow data in binary format
a = fread(fid, 3, 'int');
Nx = a(1); % number of points in x direction
Ny = a(2); % number of points in y direction
Nz = a(3); % number of points in z direction
Ma = fread(fid, 1, 'float');
some_num = fread(fid, 1, 'float');
Re = fread(fid, 1, 'float');
time = fread(fid, 1, 'float');
xx1 = fread(fid, 2*Nx*Ny*Nz, 'float');
xx1 = reshape(xx1, [Nx, 2*Ny, Nz]);
fclose(fid);
[XX, YY] = meshgrid(x, y);
% plot (squeeze(xx1(2,:,1)));
h = pcolor(XX, YY, squeeze(xx1)');
set(h, 'EdgeColor', 'none');
colorbar
Python代码:
import struct
import numpy
import matplotlib
unpackformat_int = '<i'
unpackformat_flo = '<f'
fid = open('FLOW_phys_GRID_1.xyz', 'r+')
Nx = struct.unpack(unpackformat_int,fid.read(4))[0]
Ny = struct.unpack(unpackformat_int,fid.read(4))[0]
Nz = struct.unpack(unpackformat_int,fid.read(4))[0]
aa = Nx*Ny*Nz
xx = struct.unpack('i'*aa, fid.read(aa*4))[0]
yy = struct.unpack('i'*aa, fid.read(aa*4))[0]
xx = xx.reshape([Nx, Ny])
yy = yy.reshape([Nx, Ny])
fid.close()
fid = open('FLOW_phys.raw', 'r+')
Nx = struct.unpack(unpackformat_int,fid.read(4))[0]
Ny = struct.unpack(unpackformat_int,fid.read(4))[0]
Nz = struct.unpack(unpackformat_int,fid.read(4))[0]
Ma = struct.unpack(unpackformat_flo, fid.read(4))[0]
some = struct.unpack(unpackformat_flo, fid.read(4))[0]
Re = struct.unpack(unpackformat_flo, fid.read(4))[0]
time = struct.unpack(unpackformat_flo, fid.read(4))[0]
bb = Nx*Ny*Nz
xx1 = struct.unpack('f'*bb, fid.read(bb*4))[0]
xx2 = struct.unpack('f'*bb, fid.read(bb*4))[0]
xx1 = xx1.reshape([Nx, Ny, Nz])
xx2 = xx2.reshape ([Nx, Ny, Nz])
fid.close()
[XX, YY] = numpy.meshgrid(xx, yy)
matplotlib.plot(XX,YY,xx2)
最佳答案
没有特定的错误消息,很难分辨。但是,我看到了一系列可能的问题。
第一:
fid = open('FLOW_phys_GRID_1.xyz', 'r+')
这应该是
'rb'
,表示“读取二进制”。这是一个二进制文件,而不是文本文件。 'r+'
表示“读和写”,但您不是写。另外,您应始终使用with open('FLOW_phys_GRID_1.xyz', 'r+') as fid:
,因为完成后,它将自动安全地关闭文件。同样,在MATLAB中,打开的文件由特殊数字表示,这些数字向MATLAB解释器标识该文件。但是,在Python中,它们是不同的对象,因此,为了更好地记住这一点,最好使用
fobj
代替fid
作为变量名。下一个:
xx = struct.unpack('i'*aa, fid.read(aa*4))[0]
yy = struct.unpack('i'*aa, fid.read(aa*4))[0]
在MATLAB中,您将其读取为浮点数,但是在python中,您将其读取为整数。更重要的是,虽然您正在读取
aa
数字,但是[0]
仅保留第一个数字。在MATLAB中,请保留所有这些。下一个:
xx = xx.reshape([Nx, Ny])
yy = yy.reshape([Nx, Ny])
unpack
返回一个本质上是一维的元组。它没有reshape
方法,这是numpy数组所具有的,但没有python列表或元组。您将需要使用xx
之类的方法将yy
和xx = np.array(xx).reshape([Nx, Ny])
转换为numpy数组,或者最好使用numpy的fromfile
,例如xx = np.fromfile(fid, dtype='float', count=aa)
。这将直接以numpy数组形式读取数据。实际上,我建议您到处使用它。获得
Nx
,Ny
和Nz
的部分可以简化为Nx, Ny, Nz = np.fromfile(fid, dtype='i', count=3)
。该语法实际上也可以用于unpack
,但是当处理文件时,numpy方法要简单一些。同样,在numpy和MATLAB中,维度的顺序也不同。 numpy(默认情况下)使用从C编程语言数组派生的顺序,而MATLAB仅使用Fortran编程语言的顺序。因此,要在Python中获得与MATLAB中相同的数组形状,您需要先将其反转为轴,以
reshape([Ny, Nx])
或以后以reshape([Ny, Nx, Nz])
表示。此外,这仅在
Nz
始终为1的情况下有效。如果为其他任何数字,即使在MATLAB中也将失败。接下来,从MATLAB代码中:
x = squeeze(xx(:,1));
y = squeeze(yy(1,:));
您永远不会在Python中执行此操作。这也意味着Python中的以下部分与您在MATLAB中所做的不同:
[XX, YY] = numpy.meshgrid(xx, yy)
下一个:
bb = Nx*Ny*Nz
xx1 = struct.unpack('f'*bb, fid.read(bb*4))[0]
xx2 = struct.unpack('f'*bb, fid.read(bb*4))[0]
在MATLAB中,您读
2*Nx*Ny*Nz
,但是在Python中,您将Nx*Ny*Nz
读入两个不同的数组,而这些数组永远都不会合并为一个。这意味着您在Python中绘制的内容与在MATLAB中绘制的有所不同。您也永远不会squeeze
或转置numpy数组。最后:
matplotlib.plot(XX,YY,xx2)
首先,您在MATLAB中执行
pcolor
,但在Python中执行plot
。这些是完全不同的。 matplotlib像MATLAB一样具有pcolor
,因此请使用它。其次,没有
matplotlib.plot
之类的东西。您需要先执行from matplotlib import pyplot
然后执行pyplot.plot
之类的操作。然后,您需要执行pyplot.show()
来实际显示绘图。但是,通常惯例是执行import matplotlib.pyplot as plt
(和import numpy as np
)来使内容更短。如果以交互方式而不是在脚本中执行此操作,则可以执行
plt.ion()
以便立即显示该图(或者最好使用IPython shell并使用%matplotlib
)。但是在脚本中,完成所有格式化后,您需要调用plt.show()
。因此,这就是我(大致)实现您正在做的事情的方式。我没有要测试的示例文件,因此它可能无法正常运行,但希望它足以使您入门:
import numpy as np
import matplotlib.pyplot as plt
with open('FLOW_phys_GRID_1.xyz', 'rb') as fobj:
Nx, Ny, Nz = np.fromfile(fobj, 'int32', 3)
x = np.fromfile(fobj, 'float32', Nx*Ny*Nz).reshape(Ny, Nx, Nz)[:, 0, 0])
y = np.fromfile(fobj, 'float32', Nx*Ny*Nz).reshape(Ny, Nx, Nz)[0, :, 0]
with open('FLOW_phys.raw', 'rb') as fobj:
Nx, Ny, Nz = np.fromfile(fobj, 'int32', 3)
xx1 = np.fromfile(fobj, 'float32', 2*Nx*Ny*Nz).reshape(2*Ny, Nx, Nz).squeeze().T
plt.pcolor(*np.meshgrid(x, y), xx1)
plt.show()
关于python - 读取二进制数据并将数据分布在网格文件Python中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36681586/