2012-05-07 28 views
5

Tôi hoàn toàn mới đối với Python và đang viết mã trực quan bằng Python từ đầu (để tránh sử dụng các chương trình độc quyền đắt tiền như IDL). Cho đến bây giờ tôi đã sử dụng IDL và gnuplot. Những gì tôi muốn có thể làm là:Đọc truy cập trực tiếp tập tin chưa định dạng trong Python

Tôi viết mảng hai chiều thành tệp truy cập trực tiếp chưa được định dạng bằng fortran mà tôi muốn đọc trong python. Mã thử nghiệm chính xác được đưa ra dưới đây. Mã thực tế là một mã song song khổng lồ nhưng đầu ra dữ liệu gần giống với định dạng chính xác.

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 

Chương trình sẽ cung cấp cho tôi số không cho t = 1 và tăng số lượng "đảo" để tăng giá trị của t. Nhưng khi tôi đọc nó bằng cách sử dụng mã python đưa ra dưới đây, tôi chỉ nhận được số không. Nếu tôi xóa câu lệnh viết đầu tiên của số không, tôi chỉ nhận được lát thời gian đầu tiên bất kể giá trị của "timeslice" mà tôi sử dụng trong mã python. Mã tôi có cho đến thời điểm này là:

#!/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() 

Tôi muốn def readslice để có thể đọc bản ghi tại địa điểm thứ i nếu timeslice bằng i. Cho rằng tôi đã cố gắng sử dụng f.seek nhưng nó dường như không hoạt động. numpy.fromfile dường như bắt đầu đọc từ bản ghi đầu tiên. Làm thế nào để làm cho numpy.fromfile để đọc từ một điểm cụ thể trong một tập tin?

Tôi vẫn đang cố gắng làm quen với kiểu Python và tìm hiểu thông qua tài liệu. Bất kỳ trợ giúp và con trỏ sẽ được đánh giá rất nhiều.

+1

không chắc chắn bạn đang làm gì, nhưng hãy lưu ý đến VTK. – Anycorn

+1

Tôi làm điều này thường xuyên (truy cập trực tiếp Fortran + tìm kiếm tập tin python + numpy.fromfile). Mã của bạn có vẻ chính xác. Hãy thử đọc dữ liệu của bạn từ một chương trình Fortran như là một kiểm tra sanity. Ngoài ra, hãy đăng đoạn mã Fortran mà bạn sử dụng để ghi dữ liệu. Đảm bảo dữ liệu bạn viết/đọc là cùng một độ chính xác/kiểu dữ liệu. Bạn nói những gì bạn đang làm dường như không hoạt động. Bạn có thể bao gồm một ví dụ về dữ liệu sẽ trông như thế nào và những gì bạn đang thực sự nhận được? – milancurcic

+0

IRO-bot, bạn có thể chia sẻ đoạn mã của mình nơi bạn đọc các tệp như vậy không?Mã này dường như bắt đầu từ bản ghi đầu tiên mọi lúc. Tài liệu cho np.fromfile dường như không có từ khóa cho điểm bắt đầu đọc dữ liệu. – toylas

Trả lời

6

Dưới đây là một mã python mà sẽ làm việc cho bạn:

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 

Trong mã ban đầu của bạn, bạn đã đi qua tên tập tin như là đối số đầu tiên np.fromfile thay vì đối tượng tập tin f. Do đó, np.fromfile đã tạo đối tượng tệp mới thay vì sử dụng đối tượng bạn dự định. Đây là lý do tại sao nó tiếp tục đọc từ đầu của tập tin. Ngoài ra, f.seek lấy số byte làm đối số, không phải số lượng phần tử. Tôi đã mã hóa nó thành 8 để phù hợp với dữ liệu của bạn, nhưng bạn có thể thực hiện điều này nếu bạn muốn. Ngoài ra, đối số trường trong readslice là không cần thiết. Hi vọng điêu nay co ich.

+0

Cảm ơn rất nhiều IRO-bot !! Cuối cùng đó là sai lầm ngu ngốc của tôi !! Cảm ơn đã chỉ ra điều đó! Bây giờ mọi thứ hoạt động hoàn hảo tốt !!! – toylas

+0

@toylas Chắc chắn, tôi rất vui vì đã giúp. – milancurcic

+0

Xong! Tôi đã cố gắng +1 nó nhưng không được phép vì tôi chưa có "danh tiếng" :-p Nhấp vào dấu kiểm. Tôi vẫn còn rất mới vào trang web này. – toylas

1

Tôi không nghĩ rằng tất cả các thời gian chạy FORTRAN đều giống nhau; một số bản ghi khung, một số không, và tôi không tự tin rằng những người làm khung hình sẽ tất cả cùng làm theo cách đó. Họ thường có thể đọc lại các hồ sơ được viết bởi chính họ, nhưng interop từ một thời gian chạy FORTRAN khác có thể không có ở đó.

Có lẽ bạn nên viết một chương trình thử nghiệm nhỏ trong FORTRAN đã chọn, ghi một vài bản ghi tương tự mã sản xuất của bạn và sau đó chọn các kết quả bằng trình chỉnh sửa tệp nhị phân ưa thích của bạn - Tôi thích bpe, nhưng có nhiều trong số họ có sẵn.

Sau đó, sau khi bạn hiểu những gì thực sự được viết, hãy kéo mọi thứ trở lại bằng cách sử dụng mô-đun cấu trúc Python hoặc tương tự.

BPE: http://sourceforge.net/projects/bpe/

+1

Cảm ơn câu trả lời nhưng như IRO-bot đã chỉ ra ở trên, các tệp truy cập trực tiếp không có bất kỳ thông tin ghi nào. Tôi luôn đọc những tập tin đó trong IDL. Và điều này độc lập với trình biên dịch. Tôi đã thử mô-đun cấu trúc nhưng tôi chưa hiểu đủ về python. Vì vậy, tôi đã không thể thực hiện nó. Numpy.fromfile ở trên là triển khai gần nhất ngoài vấn đề tìm kiếm. – toylas

Các vấn đề liên quan