4

私は値の1次元配列を持っています

i = np.arange(0,7,1)

と関数

# Returns a column matrix
def fn(i):
    return np.matrix([[i*2,i*3]]).T


fnv = np.vectorize(fn) 

それから書く

fnv(i)

私にエラーを与える

  File "<stdin>", line 1, in <module>
  File "c:\Python33\lib\site-packages\numpy\lib\function_base.py", 
        line 1872, in __call__
    return self._vectorize_call(func=func, args=vargs)
  File "c:\Python33\lib\site-packages\numpy\lib\function_base.py", 
        line 1942, in _vectorize_call
        copy=False, subok=True, dtype=otypes[0])
  ValueError: setting an array element with a sequence.

私が探している結果は、入力配列と同じ数の列と 2 つの行を持つ行列です。これを達成するためのnumpyでの最良の表記法は何ですか?

たとえば、は等しいでしょう

[1,2,3,4,5,6]

出力は等しくなります

[[2,4,6,8,10,12],
 [3,6,9,12,15,18]]
4

2 に答える 2

6

EDITの 使用を避けるようにしてくださいvectorize。効率が悪いという錯覚を与えるためですが、その内部にはすべての python ループがあります。

ints を受け取ってmatrix形状の を返すユーザー提供の関数を実際に処理する必要がある場合(2, 1)は、おそらくできることはあまりありません。しかし、それは本当に奇妙なユースケースのようです。intを受け取ってを返し、必要に応じintて使用する関数のリストでそれを置き換えることができる場合ufuncs、つまりnp.sinの代わりにmath.sin、次のことができます。

def vectorize2(funcs) :
    def fnv(arr) :
        return np.vstack([f(arr) for f in funcs])
    return fnv

f2 = vectorize2((lambda x : 2 * x, lambda x : 3 * x))

>>> f2(np.arange(10))
array([[ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18],
       [ 0,  3,  6,  9, 12, 15, 18, 21, 24, 27]])

参考までに、提案されたベクトル化に対してこのベクトル化のタイミングを計りました。

f = vectorize(fn)


>>> timeit.timeit('f(np.arange(10))', 'from __main__ import np, f', number=1000)
0.28073329263679625
>>> timeit.timeit('f2(np.arange(10))', 'from __main__ import np, f2', number=1000)
0.023139129945661807


>>> timeit.timeit('f(np.arange(10000))', 'from __main__ import np, f', number=10)
2.3620706288432984
>>> timeit.timeit('f2(np.arange(10000))', 'from __main__ import np, f2', number=10)
0.002757072593169596

そのため、小さな配列でも 1 桁の速度があり、大きな配列ではほぼ無料で利用できる x1000 の速度アップにまで成長します。

元の答え

回避策がない限り使用しないでくださいvectorize。遅いです。次の例を参照してください

>>> a = np.array(range(7))
>>> a
array([0, 1, 2, 3, 4, 5, 6])
>>> np.vstack((a, a+1))
array([[0, 1, 2, 3, 4, 5, 6],
       [1, 2, 3, 4, 5, 6, 7]])
>>> np.vstack((a, a**2))
array([[ 0,  1,  2,  3,  4,  5,  6],
       [ 0,  1,  4,  9, 16, 25, 36]])

関数が何であれ、numpy の ufuncs で構築できる場合は、次のようなことを実行して、必要なものnp.vstack((a, f(a)))を取得できます。

于 2013-01-08T14:40:56.323 に答える
0

ベクトル化を単純に再実装すると、必要なものが得られます

def vectorize( fn):
    def do_it (array):
        return np.column_stack((fn(p) for p in array))
    return do_it

これが効率的でない場合、またはより良い方法がある場合は、お知らせください。

于 2013-01-08T15:08:35.193 に答える