2010-12-21 11 views
9

numpy vectorize関数は便利ですが、関数の引数がスカラーではなくリストである場合はうまく動作しません。例として:リストを引数として使用してナンキーベクトル化

type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'numpy.int64'>, A=1 

Traceback (most recent call last): 
    File "vectorize.py", line 14, in <module> 
    f2(X,P) 
    File "/usr/local/lib/python2.6/dist-packages/numpy/lib/function_base.py", line 1824, in __call__ 
    theout = self.thefunc(*newargs) 
    File "vectorize.py", line 5, in f 
    return sum(A)/x 
TypeError: 'numpy.int64' object is not iterable 

私は関数fがそれをINGのvectorizeずにだけで正常に動作することを理解し、私はどのように(一般的に)ベクトル化を知りたい:

import numpy as np 

def f(x, A): 
    print "type(A)=%s, A=%s"%(type(A),A) 
    return sum(A)/x 

X = np.linspace(1,2,10) 
P = [1,2,3] 

f2 = np.vectorize(f) 

f(X,P) 
f2(X,P) 

を与えます引数がスカラーではなくリストを取る関数。

答えて

11

ベクトル化された関数からどのような出力を見たいのかはっきりしませんが、f()のすべての引数に同じリスト(A)を適用したいとします。 )(つまり、X配列内の各要素に対して1回)

関数のベクトル化されたバージョンでは、すべての引数が配列であることを保証し、numpy's broadcasting rulesを適用してこれらの引数を組み合わせる方法を決定します。

np.arrayのnp.ndarrayのラッピングと同様に、配列への引数の強制は、リストをdtype = objectの配列にするのではなく、同じ要素を含む配列に自動的に変換することで役立ちます。その唯一の要素としてリストを含んでいます。ほとんどの場合、これが私たちが望むものですが、あなたの場合、この「スマート」な行動があなたをかむために戻ってきています。

のみベクトルとして特定の入力を処理するためにnumpyのを指示する方法があるかもしれないが、あなたは後にしている動作を取得するには、2つの簡単な方法があります:

  1. は、手動で放送内で作業するarray with dtype=objectを作成ルール
  2. Curry前関数を

1 DTYPE =オブジェクト

をベクトルに値

numpyのアレイは、アイテムの一つのタイプを記憶からその効率を導出するが、それらはまだ格納されたデータ型がPythonオブジェクトであることを指定することにより、任意のPythonオブジェクトを含むことができる:

list_obj_array = np.ndarray((1,), dtype=object) 
list_obj_array[0] = [1,2,3] 
f2(X,list_obj_array) # using your definition from above 

プリント:

type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 

とリターン:

array([ 6.  , 5.4  , 4.90909091, 4.5  , 4.15384615, 
     3.85714286, 3.6  , 3.375  , 3.17647059, 3.  ]) 

2。あなたは、配列内の各アイテムの関数呼び出しに同じリストを渡しているので、あなたはベクトル化を適用する前に、カリー化により機能を直接リストを格納することができ

をカリー:

def curry_f(A): 
    def f_curried(x): 
     return f(x, A) # using your definition from above 
    return f_curried 

f2 = np.vectorize(curry_f(P)) 
f2(X) 

プリント:

type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 

とリターン:

array([ 6.  , 5.4  , 4.90909091, 4.5  , 4.15384615, 
     3.85714286, 3.6  , 3.375  , 3.17647059, 3.  ]) 

P. np.frompyfuncを見ることもできます。これはvectorize()と似ていますが、やや低いレベルで動作します。

0

これは私が現在、最初の引数として1次元配列を受け取る関数をベクトル化するために使用している再帰的なデコレータの例である:私はそれがほとんど同じnp.vectorizeなどないと思い

def broadcast(fvec): 
    def inner(vec, *args, **kwargs): 
     if len(vec.shape) > 1: 
      return np.array([inner(row, *args, **kwargs) for row in vec]) 
     else: 
      return fvec(vec, *args, **kwargs) 
    return inner 

が、私は仕事のためにvectorize/frompyfuncを適応させることを試みるよりも、これを使う方が簡単でした。

関連する問題