2012-06-28 45 views
6

Tôi có một mảng được đọc từ một chương trình con fortran dưới dạng mảng 1D qua f2py. Sau đó, trong python, mảng đó được định cấu hình lại:f2py - ngăn chặn sắp xếp lại mảng

a=np.zeros(nx*ny*nz) 
read_fortran_array(a) 
a=a.reshape(nz,ny,nx) #in fortran, the order is a(nx,ny,nz), C/Python it is reversed 

Bây giờ tôi muốn chuyển mảng đó trở lại fortran dưới dạng mảng 3D.

some_data=fortran_routine(a) 

Vấn đề là f2py cố gắng chuyển vị trí trước khi chuyển đến fortran_routine. thói quen fortran trông giống như:

subroutine fortran_routine(nx,ny,nz,a,b) 
real a 
real b 
integer nx,ny,nz 
!f2py intent(hidden) nx,ny,nz 
!f2py intent(in) a 
!f2py intent(out) b 
... 
end subroutine 

Làm thế nào để ngăn chặn tất cả các transposing lui? (Tôi hoàn toàn hài lòng khi sử dụng các quy ước lập chỉ mục mảng khác nhau trong hai ngôn ngữ).

EDIT

Dường như np.asfortranarray hoặc np.flags.f_contiguous nên có một số phần trong giải pháp, tôi chỉ có thể dường như không tìm ra những gì phần đó là (hoặc có thể là một ravel theo sau là một reshape(shape,order='F')?

EDIT

có vẻ như bài này đã gây ra một số rắc rối. vấn đề ở đây là f2py nỗ lực để bảo vệ lược đồ lập chỉ mục thay vì bố cục bộ nhớ . Vì vậy, nếu tôi có một mảng numpy (theo thứ tự C) với hình dạng (nz, ny, nx), sau đó f2py cố gắng để làm cho mảng có hình dạng (nz, ny, nx) trong fortran quá. Nếu f2py được giữ lại bố cục bộ nhớ, mảng sẽ có hình dạng (nz, ny, nx) trong python và (nx, ny ,nz) trong fortran. Tôi muốn bảo tồn bố cục bộ nhớ.

+0

hi mgilson, một câu hỏi nhanh về vấn đề này. Tôi đã viết một mã fortran mà mất một mảng 3d như đầu vào: – toylas

Trả lời

2

Dường như câu trả lời là hợp lý đơn giản:

b=np.ravel(a).reshape(tuple(reversed(a.shape)),order='F') 

công trình, nhưng rõ ràng, đây là điều tương tự như:

b=a.T 

kể từ khi chuyển vị trả một cái nhìn và một cái nhìn lướt qua b.flags so với a.flags cho thấy đây là những gì tôi muốn. (b.flags là F_CONTIGUOUS).

+0

Giải pháp cực kỳ dễ dàng cho những gì có vẻ là một vấn đề rất phức tạp. Câu trả lời chính xác. – Chiel

5

Fortran không đảo ngược thứ tự trục, nó chỉ lưu trữ dữ liệu trong bộ nhớ khác với C/Python. Bạn có thể yêu cầu lưu trữ dữ liệu theo thứ tự Fortran không giống như đảo ngược các trục.

tôi sẽ viết lại mã của bạn như thế này

a=np.zeros(nx*ny*nz) 
read_fortran_array(a) 
a=a.reshape(nx,ny,nz, order='F') # It is now in Fortran order 

Bây giờ, f2py sẽ không cố gắng để sắp xếp lại mảng khi đi qua.

Như một mặt lưu ý, điều này cũng sẽ làm việc

a=a.reshape(nx,ny,nz) # Store in C order 

vì đằng sau hậu trường, f2py thực hiện các hoạt động này khi bạn vượt qua một mảng C-để một thói quen Fortran:

a=a.flatten() # Flatten array (Make 1-D) 
a=a.reshape(nx,ny,nz, order='F') # Place into Fortran order 

Nhưng tất nhiên nó hiệu quả hơn để lưu trữ trong thứ tự Fortran ngay từ đầu.

Nói chung, bạn không cần phải lo lắng về việc sắp xếp thứ tự mảng trừ khi bạn có phần quan trọng về hiệu suất vì f2py sẽ xử lý việc này cho bạn.

+0

Thậm chí đơn giản hơn sẽ được thông qua thứ tự = 'F' paramter để gọi ban đầu để numpy.zeros. Sau đó không cần định hình lại hoặc sắp xếp lại. – DaveP

+0

Tôi xin lỗi về phản hồi chậm trên trang này (Tôi đã ra khỏi thành phố). Tôi thực sự không hiểu giải pháp của bạn ở đây. 'a = a.reshape (nx, ny, nz)' là * không phải cái tôi muốn * vì 'nx' được cho là chỉ số nhanh (đây là chỉ số chậm). Tôi không thể sử dụng các giải pháp đầu tiên kể từ khi tôi đã viết nhiều mã hơn giả sử C/Python lập chỉ mục trên phía python. Tôi đã thử 'b = a.flatten(). Reshape (tuple (đảo ngược (a.shape)), order = 'F')', nhưng điều đó không hiệu quả (Error: '0-th dimension phải được sửa thành 0 nhưng có 448'). – mgilson

+1

xin lỗi. Lỗi ID10T. PEBKAC, bất cứ điều gì. 'b = a.flatten(). reshape (tuple (đảo ngược (a.shape)), order = 'F')' không hoạt động (Cảm ơn ý tưởng). Hiệu quả ở đây không phải là một vấn đề kể từ khi numpy không làm cho một bản sao của dữ liệu mảng, chỉ có một sự thay đổi cho siêu dữ liệu. Các 'đảo ngược' không cần phải có kể từ khi tôi đang sử dụng C/Python lập chỉ mục trong phần C/Python và Fortran lập chỉ mục trong phần fortran của mã. Nó có ý nghĩa nhất (đối với tôi) theo cách đó. (Nếu bạn cập nhật bài viết của bạn để bao gồm điều này, tôi sẽ vui vẻ chấp nhận nó câu trả lời của bạn). – mgilson

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