I try to read a 2d array with floats from a binary file with Python. Files have been written with big endian by a Fortran program (it is the intermediate file of the Weather Research and Forecast model). I already know dimension sizes of the array to read (nx & ny) but as a Fortran and IDl programer I am completely lost, how to manage it in Python. (Later on I want to visualize the array).
- Shall I use
struct.unpackornumpy.fromfileor thearray module? - Do I have to read first a vector and afterwards reshape it? (have seen this option only for the numpy-way)
- How do I define a 2d array with numpy and how do I define the dtype to read with big-endian byte ordering?
- Is there an issue with array ordering (column or row wise) to take into account?
Armali
19.6k15 gold badges64 silver badges185 bronze badges
1 Answer 1
Short answers per sub-question:
- I don't think the
arraymodule has a way to specify endianness. Between thestructmodule and Numpy I think Numpy is easier to use, especially for Fortran-like ordered arrays. - All data is inherently 1-dimensional as far as the hardware (disk,
RAM, etc) is concerned, so yes reshaping to get a 2D representation
is always necessary. With
numpy.fromfilethe reshape must happen explicitly afterwards, butnumpy.memmapprovides a way to reshape more implicitly. - The easiest way to specify endianness with Numpy is to use a short
type string, actually very similar to the approach needed for
the
structmodule. In Numpy>fand>f4specify single precision and>dand>f8double precision big-endian floating point. - Your binary file could walk the array along the rows (C-like) or along
the columns (Fortran-like). Whichever of the two, this has to be taken into
account to represent the data properly. Numpy makes this easy with the
orderkeyword argument forreshapeandmemmap(among others).
All in all, the code could be for example:
import numpy as np
filename = 'somethingsomething'
with open(filename, 'rb') as f:
nx, ny = ... # parse; advance file-pointer to data segment
data = np.fromfile(f, dtype='>f8', count=nx*ny)
array = np.reshape(data, [nx, ny], order='F')
Sign up to request clarification or add additional context in comments.
1 Comment
Klem
Many thanks, moarningsun ! Your explanations helped me to solve the problem !
Explore related questions
See similar questions with these tags.
lang-py
nx*nybig-endian numbers?scipy.io.FortranFile(docs.scipy.org/doc/scipy/reference/generated/…). Note the comments in the docstring; whether or notFortranFilewill work depends on the Fortran compiler.