2015-06-22 16 views
5

Đây là vấn đề của tôi: Tôi thao tác 432*46*136*136 lưới đại diện cho time*(space) được bao gồm trong mảng có nhiều mảng và trăn. Tôi có một mảng alt, bao gồm độ cao của các điểm lưới và một mảng khác temp lưu trữ nhiệt độ của các điểm lưới.Chuyển đổi lưới numpy của Python sử dụng các chức năng phổ quát

Đó là vấn đề đối với một so sánh: nếu T1T2 hai kết quả, T1[t0,z0,x0,y0]T2[t0,z0,x0,y0] đại diện cho nhiệt độ tại H1[t0,z0,x0,y0] và mét, tương ứng. Nhưng tôi muốn so sánh nhiệt độ của các điểm ở cùng độ cao, không phải ở cùng một điểm lưới.

Do đó, tôi muốn sửa đổi trục z của ma trận để biểu thị độ cao chứ không phải điểm lưới. Tôi tạo ra một hàm conv(alt[t,z,x,y]) thuộc tính số từ -20 đến 200 cho mỗi độ cao. Đây là mã của tôi:

def interpolation_extended(self,temp,alt): 
    [t,z,x,y]=temp.shape 
    new=np.zeros([t,220,x,y]) 
    for l in range(0,t): 
     for j in range(0,z): 
      for lat in range(0,x): 
      for lon in range(0,y): 
       new[l,conv(alt[l,j,lat,lon]),lat,lon]=temp[l,j,lat,lon] 
    return new 

Nhưng điều này chắc chắn mất quá nhiều thời gian, tôi không thể làm việc này. Tôi đã cố gắng viết nó bằng cách sử dụng các chức năng phổ quát với numpy:

def interpolation_extended(self,temp,alt): 
    [t,z,x,y]=temp.shape 
    new=np.zeros([t,220,x,y]) 
    for j in range(0,z): 
     new[:,conv(alt[:,j,:,:]),:,:]=temp[:,j,:,:] 
    return new 

Nhưng điều đó không hiệu quả. Bạn có bất kỳ ý tưởng làm điều này trong python/numpy mà không cần sử dụng 4 vòng lồng nhau?

Cảm ơn bạn

+0

Điều đó có thể là do các cuộc gọi hàm trong Python rất tốn kém. Tính toán trước tọa độ 'conv' với ví dụ: Phương thức numpy 'fromfunction' có thể hữu ích. – Ashalynd

+0

Có lớn hơn 220 không? Nếu đó là trường hợp tôi có thể thấy lý do mã của bạn sẽ bị lỗi. – jfish003

+0

Có phải 'conv' là bất kỳ kết hợp/hàm tuyến tính nào của' alt' không? Bạn có thể đưa ra một ví dụ hoặc đăng mã của bạn cho 'conv' không? Nếu 'conv' có thể được vector hóa, bạn có thể viết nó trong 1 lớp lót. –

Trả lời

3

tôi có thể không thật sự cố gắng mã kể từ khi tôi không có ma trận của bạn, nhưng một cái gì đó như thế này nên thực hiện công việc.

Thứ nhất, thay vì tuyên bố conv như một chức năng, được chiếu toàn bộ độ cao cho tất cả các dữ liệu của bạn:

conv = np.round(alt/500.).astype(int) 

Sử dụng np.round, phiên bản numpys của hình tròn, nó vòng tất cả các yếu tố của ma trận bởi vectorizing hoạt động trong C, và do đó, bạn nhận được một mảng mới rất nhanh (ở tốc độ C). Dòng sau để căn độ cao sẽ bắt đầu vào 0, bằng cách chuyển tất cả các mảng theo giá trị tối thiểu của nó (trong trường hợp của bạn, -20):

conv -= conv.min() 

dòng trên sẽ chuyển đổi ma trận độ cao của bạn từ [-20, 200 ] đến [0, 220] (tốt hơn để lập chỉ mục).

Với điều đó, suy thể được thực hiện dễ dàng bằng cách chỉ số đa chiều:

t, z, y, x = np.indices(temp.shape) 

các vectơ trên chứa tất cả các chỉ số cần thiết để chỉ số ma trận ban đầu của bạn. Sau đó, bạn có thể tạo ma trận mới bằng cách thực hiện:

new_matrix[t, conv[t, z, y, x], y, x] = temp[t, z, y, x] 

không có bất kỳ vòng lặp nào.

Hãy cho tôi biết nếu nó hoạt động. Nó có thể cung cấp cho bạn một số erros kể từ khi là khó khăn cho tôi để kiểm tra nó mà không có dữ liệu, nhưng nó sẽ làm công việc.


sau Ví dụ đồ chơi hoạt động tốt:

A = np.random.randn(3,4,5) # Random 3x4x5 matrix -- your temp matrix 
B = np.random.randint(0, 10, 3*4*5).reshape(3,4,5) # your conv matrix with altitudes from 0 to 9 
C = np.zeros((3,10,5)) # your new matrix 

z, y, x = np.indices(A.shape) 
C[z, B[z, y, x], x] = A[z, y, x] 

C chứa kết quả của bạn theo độ cao.

+0

Điều đó hoạt động hoàn hảo, cảm ơn bạn rất nhiều. Tôi thậm chí không biết về khả năng làm việc với các chỉ số như vectơ. Tôi phải thay đổi: 'conv = np.round (alt/500.)' thành 'conv = np.round (alt/500.). Astype (int)' để sử dụng conv làm chỉ mục. –

+0

@Arnaud PROST cảm ơn! Đã chỉnh sửa. Chỉ số vector rất hữu ích. Ví dụ: 'A [[3, 7, 8],:]' (đối với mảng 'A' 2D) sẽ trả về hàng thứ 4, thứ 8 và thứ 9 của ma trận. Câu trả lời bằng cách sử dụng 'np.indices' là một phần mở rộng cho điều đó bằng cách lập chỉ mục tất cả các phần tử của tất cả các trục trong một mảng đa chiều. –

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