web-dev-qa-db-ja.com

numpy配列の行をフィルタリングしますか?

Numpy配列の各行に関数を適用しようとしています。この関数がtrueと評価された場合、行を保持します。それ以外の場合は破棄します。たとえば、私の機能は次のようになります。

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

次のようなものがあるかどうか疑問に思っていました。

np.apply_over_axes()

numpy配列の各行に関数を適用し、結果を返します。私は次のようなものを期待していた:

np.filter_over_axes()

numpy配列の各行に関数を適用し、関数がtrueを返した行のみを返します。このようなものはありますか?または、単にforループを使用する必要がありますか?

24
kyphos

理想的には、関数のベクトル化バージョンを実装し、それを使用して boolean indexing を実行できます。大多数の問題にとって、これは正しい解決策です。 Numpyは、すべての基本的な操作と比較だけでなく、さまざまな軸に対して機能できる非常に多くの関数を提供するため、最も有用な条件はベクトル化可能でなければなりません。

import numpy as np

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

上記を実行できないと確信している場合は、リスト内包表記(または np.apply_along_axis )インデックス付けするブールの配列を作成します。

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

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

これにより、比較的クリーンな方法でジョブが実行されますが、ベクトル化されたバージョンよりも大幅に遅くなります。例:

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
30
Roger Fan