2014-10-02 14 views
15

Tôi đang tìm cách áp dụng một hàm cho mỗi hàng của một mảng có nhiều mảng. Nếu hàm này đánh giá đúng, tôi sẽ giữ hàng, nếu không tôi sẽ loại bỏ nó. Ví dụ, chức năng của tôi có thể là:Lọc các hàng của một mảng có nhiều mảng?

def f(row): 
    if sum(row)>10: return True 
    else: return False 

Tôi đã tự hỏi nếu có điều gì đó tương tự như:

np.apply_over_axes() 

áp dụng một chức năng để mỗi hàng của một mảng NumPy và trả về kết quả. Tôi đã hy vọng cho một cái gì đó như:

np.filter_over_axes() 

sẽ áp dụng một hàm cho mỗi hàng của một mảng có nhiều mảng và chỉ trả về các hàng mà hàm trả về true. Có thứ gì như thế này không? Hoặc tôi nên sử dụng một vòng lặp for?

Trả lời

24

Lý tưởng nhất là bạn có thể triển khai phiên bản vectơ của hàm và sử dụng chức năng đó để thực hiện boolean indexing. Đối với đại đa số các vấn đề này là giải pháp đúng. Numpy cung cấp khá một vài chức năng có thể hoạt động trên các trục khác nhau cũng như tất cả các hoạt động cơ bản và so sánh, vì vậy hầu hết các điều kiện hữu ích nên được vectorizable.

import numpy as np 

x = np.random.randn(20, 3) 
x_new = x[np.sum(x, axis=1) > .5] 

Nếu bạn biết chắc chắn rằng bạn không thể làm các việc trên, tôi sẽ đề nghị sử dụng một sự hiểu biết danh sách (hoặc np.apply_along_axis) để tạo ra một mảng của bools chỉ mục với.

def myfunc(row): 
    return sum(row) > .5 

bool_arr = np.array([myfunc(row) for row in x]) 
x_new = x[bool_arr] 

Thao tác này sẽ hoàn thành công việc một cách tương đối rõ ràng, nhưng sẽ chậm hơn đáng kể so với phiên bản vectơ. Ví dụ:

x = np.random.randn(5000, 200) 

%timeit x[np.sum(x, axis=1) > .5] 
# 100 loops, best of 3: 5.71 ms per loop 

%timeit x[np.array([myfunc(row) for row in x])] 
# 1 loops, best of 3: 217 ms per loop 
+0

Cảm ơn Roger, hàm tôi muốn sử dụng phức tạp hơn một chút so với chỉ lấy tổng, vì vậy tôi có thể sử dụng giải pháp đọc danh sách. – kyphos

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