2014-04-28 25 views
5

Tôi đã thấy một vài mã sử dụng numpy.apply_along_axis và tôi luôn phải kiểm tra mã để xem cách hoạt động của nguyên nhân vì tôi chưa hiểu ý tưởng axis bằng Python. Ví dụ: Tôi đã thử nghiệm this mã đơn giản từ tham chiếu.Hiểu trục trong Python

Tôi có thể thấy rằng đối với trường hợp đầu tiên, nó đã lấy cột đầu tiên của mỗi hàng của ma trận và trong trường hợp thứ hai, chính hàng được xem xét. Vì vậy, tôi xây dựng một ví dụ để kiểm tra cách nó hoạt động với một mảng ma trận (vấn đề đưa tôi đến câu hỏi trục này), mà cũng có thể được xem như là một ma trận 3d, trong đó mỗi hàng là một ma trận, phải không? Không.

a = [[[1,2,3],[2,3,4]],[[4,5,6],[9,8,7]]] 

import numpy 
data = numpy.array([b for b in a]) 

def my_func(x): 
    return (x[0] + x[-1]) * 0.5 

b = numpy.apply_along_axis(my_func, 0, data) 
b = numpy.apply_along_axis(my_func, 1, data) 

nào đã cho tôi:

array([[ 2.5, 3.5, 4.5], 
     [ 5.5, 5.5, 5.5]]) 

Và:

array([[ 1.5, 2.5, 3.5], 
     [ 6.5, 6.5, 6.5]]) 

Đối với kết quả đầu tiên tôi nhận được những gì tôi mong đợi. Nhưng đối với người thứ hai, tôi mặc dù tôi sẽ nhận được:

array([[ 2., 3.], 
     [ 5., 8.]]) 

Sau đó, tôi có thể phải là một axis=2 và tôi đã nhận kết quả trước đó. Vì vậy, tôi tự hỏi làm thế nào điều này hoạt động để làm việc nó đúng cách.

Cảm ơn bạn.

+0

Kết quả dự định của bạn là gì? –

Trả lời

2

Đầu tiên, data=numpy.array(a) đã đủ, không cần sử dụng numpy.array([b for b in a]).

data hiện là 3D ndarray với hình dạng (2,2,3) và có 3 trục 0, 1, 2. Trục đầu tiên có chiều dài là 2, chiều dài của trục thứ hai cũng là 2 và chiều dài trục thứ ba là 3.

Do đó cả hai numpy.apply_along_axis(my_func, 0, data)numpy.apply_along_axis(my_func, 1, data) sẽ dẫn đến một mảng 2D (2,3). Trong cả hai trường hợp, hình dạng là (2,3), các trục còn lại, thứ 2 và thứ 3 hoặc thứ 1 và thứ 3.

trả về mảng (2,2) hình dạng bạn cho thấy, nơi (2,2) là hình dạng của 2 trục đầu tiên, như bạn apply dọc theo trục thứ 3 (bằng cách đưa ra chỉ số 2).

Cách hiểu nó là bất kỳ trục nào bạn áp dụng dọc theo sẽ bị 'thu gọn' thành hình dạng my_func của bạn, trong trường hợp này trả về một giá trị duy nhất. Thứ tự và hình dạng của trục còn lại sẽ không thay đổi.

Cách khác để nghĩ về nó là: apply_along_axis có nghĩa là áp dụng hàm đó cho các giá trị trên trục đó, cho mỗi kết hợp của trục/trục còn lại. Lấy kết quả và sắp xếp chúng lại thành hình dạng của trục/trục còn lại. Vì vậy, nếu my_func trả về một tuple của 4 giá trị:

def my_func(x): 
    return (x[0] + x[-1]) * 2,1,1,1 

chúng tôi sẽ mong đợi numpy.apply_along_axis(my_func, 0, data).shape(4,2,3).

1

Có lẽ việc kiểm tra hình dạng mảng của bạn sẽ giúp làm rõ trục nào;

print data.shape 

>> (2,2,3) 

này có nghĩa là kêu gọi

numpy.apply_along_axis(my_func, 2, data) 

nên thực sự cung cấp cho một ma trận 2x2, cụ thể là

array([[ 2., 3.], 
     [ 5., 8.]]) 

3 trục (chỉ số 2) có chiều dài 3, trong khi phần còn lại các trục đều có chiều dài 2.

+0

Đây cũng là những gì tôi nhận được. Không hiểu câu hỏi của bạn là gì. : S – pceccon

+0

@pceccon: Xin lỗi tôi đã hiểu lầm; có lẽ nó sẽ giúp bạn kiểm tra hình dạng của dữ liệu - chỉnh sửa câu trả lời của tôi. – jmetz

1

Let there be một array của shape (2,2,3). Có thể thấy rằng axis 0, axis 1, axis 2 có 2, 2, 3 giá trị dữ liệu tương ứng.

Đây là những chỉ số của các phần tử của mảng

[ 
    [ 
     [(0,0,0) (0,0,1), (0,0,2)], 
     [(0,1,0) (0,1,1), (0,1,2)] 
    ], 
    [ 
     [(1,0,0) (1,0,1), (1,0,2)], 
     [(1,1,0) (1,1,1), (1,1,2)] 
    ] 
] 

Bây giờ nếu bạn áp dụng một số hoạt động cùng một số trục, sau đó thay đổi các chỉ số dọc theo trục này chỉ giữ lại những chỉ số dọc theo hai trục khác không đổi.

Ví dụ: Nếu chúng ta áp dụng một số F hoạt động cùng axis 0, sau đó các phần tử của kết quả sẽ là

[ 
    [F((0,0,0),(1,0,0)), F((0,0,1),(1,0,1)), F((0,0,2),(1,0,2))], 
    [F((0,1,0),(1,1,0)), F((0,1,1),(1,1,1)), F((0,1,2),(1,1,2))] 
] 

Cùng axis 1:

[ 
    [F((0,0,0),(0,1,0)), F((0,0,1),(0,1,1)), F((0,0,2),(0,1,2))], 
    [F((0,1,0),(1,1,0)), F((0,1,1),(1,1,1)), F((0,1,2),(1,1,2))] 
] 

Cùng axis 2:

[ 
    [F((0,0,0),(0,0,1),(0,0,2)), F((0,1,0),(0,1,1),(0,1,2))], 
    [F((1,0,0),(1,0,1),(1,0,2)), F((1,1,0),(1,1,1),(1,1,2))] 
] 

Ngoài ra hình dạng của mảng kết quả có thể được suy ra bằng cách bỏ qua trục đã cho trong hình dạng của dữ liệu đã cho.

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