textos - Lectura de un acceso directo a un archivo sin formatear en Python
lectura y escritura de archivos (2)
Aquí hay un código python que funcionará para usted:
def readslice(inputfilename,nx,ny,timeslice):
f = open(inputfilename,''rb'')
f.seek(8*timeslice*nx*ny)
field = np.fromfile(f,dtype=''float64'',count=nx*ny)
field = np.reshape(field,(nx,ny))
f.close()
return field
En su código original, estaba pasando el nombre del archivo como primer argumento a np.fromfile
lugar del objeto de archivo f
. Por lo tanto, np.fromfile
creó un nuevo objeto de archivo en lugar de usar el que pretendía. Esta es la razón por la cual siguió leyendo desde el comienzo del archivo. Además, f.seek
toma el número de bytes como argumento, no la cantidad de elementos. Lo codifiqué a 8 para que se ajuste a tus datos, pero puedes hacerlo general si lo deseas. Además, el argumento de campo en readslice
fue redundante. Espero que esto ayude.
Soy completamente nuevo en Python y estoy escribiendo mis códigos de visualización en Python desde cero (para evitar el uso de costosos programas propietarios como IDL). Hasta ahora he usado IDL y gnuplot. Lo que quiero poder hacer es esto:
Escribo arreglos bidimensionales en archivos de acceso directo sin formato usando Fortran, que quiero poder leer en Python. El código de prueba exacto se proporciona a continuación. El código real es un gran código paralelo, pero la salida de datos es casi el mismo formato.
program binary_out
implicit none
integer :: i,j,t,rec_array
double precision, dimension(100,100) :: fn
double precision, parameter :: p=2*3.1415929
INQUIRE(IOLENGTH=rec_array) fn
open(unit=10,file=''test'',status=''new'',form=''unformatted'',access=''direct'',recl=rec_array)
fn=0
write(10,rec=1) fn
do t=1,3
do i=1,100
do j=1,100
fn(i,j)=sin(i*p*t/100)*cos(j*p*t/100)
enddo
enddo
write(10,rec=t+1) fn
enddo
close(10)
end program binary_out
El programa debería darme ceros para t = 1 y aumentar el número de "islas" para aumentar el valor de t. Pero cuando lo leo usando el código python que figura a continuación, obtengo ceros. Si eliminé la primera declaración de ceros de la escritura, acabo de obtener la primera porción sin tener en cuenta el valor de "timeslice" que uso en el código python. El código que tengo hasta ahora es:
#!/usr/bin/env python
import scipy
import glob
import numpy as np
import matplotlib.pyplot as plt
import os, sys
from pylab import *
def readslice(inputfilename,field,nx,ny,timeslice):
f=open(inputfilename,''r'')
f.seek(timeslice*nx*ny)
field=np.fromfile(inputfilename,dtype=''d'',count=nx*ny)
field=np.reshape(field,(nx,ny))
return field
a=np.dtype(''d'')
a=readslice(''test'',a,100,100,2)
im=plt.imshow(a)
plt.show()
Quiero que el archivo de lectura def pueda leer un registro en el lugar i-ésimo si el ciclo de tiempo es igual a i. Por eso he tratado de usar f.seek pero parece que no funciona. numpy.fromfile parece comenzar a leer desde el primer registro. ¿Cómo hago numpy.fromfile para leer desde un punto específico en un archivo?
Todavía estoy tratando de acostumbrarme al estilo de Python y profundizar en la documentación. Cualquier ayuda y sugerencias serían muy apreciadas.
No creo que todos los tiempos de ejecución de FORTRAN sean iguales; algunos registros de cuadros, otros no, y no estoy tan seguro de que los que sí que graban marcos lo hagan de la misma manera. Por lo general, pueden leer registros escritos por ellos mismos, pero la interoperabilidad desde un tiempo de ejecución de FORTRAN a otro podría no estar allí.
Probablemente deba escribir un pequeño programa de prueba en su FORTRAN elegida, que escriba un par de registros similares a su código de producción, y luego separar los resultados usando su editor de archivos binarios favorito - Me gusta bpe, pero hay muchos disponibles.
Luego, después de que comprenda lo que realmente se está escribiendo, vuelva a utilizar el módulo de estructura de Python o similar.