2016-12-18 13 views
2

以下のコードでは、y1とy2は等しいはずですが、そうではありません。 vectorize()またはdot()にバグがありますか?グラフY1とY2のNumPy vectorize()またはdot()がバグに見える

import numpy as np 
interval = np.arange(0, 30, 0.1) 
y1 = [- 1.57 * max(0, x - 10) - 0.72 * max(0, 15 - x) 
     - 1.09 * max(0, 20 - x) for x in interval] 

def fun(x, pivot, truth): 
    if truth: return max(0, x - pivot) 
    else:  return max(0, pivot - x) 

pivots = [10, 15, 20] 
truths = [ 1, 0, 0] 
coeffs = [-1.57, -0.72, -1.09] 
y2 = [np.dot(np.vectorize(fun)(x, pivots, truths), coeffs) for x in interval] 

import matplotlib.pyplot as plt 
plt.plot(interval, y1, interval, y2) 
plt.show() 

graphed results

答えて

4

それが出力した場合、それは出力データの種類を確認するには番兵(numpy.int64)と時折あなたの関数を使用していますnumpyの適切な鋳造ルールを適用するためには整数0ザッツはmaxが返さ何それはあなたが常に最大で0.0を使用して浮動小数点数を返すように機能を変更するただし場合、計算の結果はすべての整数であるべきと仮定し、他の結果を丸めるため:

def fun(x, pivot, truth): 
    if truth: return max(0.0, x - pivot) 
    else:  return max(0.0, pivot - x) 

numpyが適用されていることを確認すると、結果は常にfloatになり、丸めは適用されません。

5

これはあなたのケースでは当てはまりませんが、vectorizeにはいくつかの秘訣があります。

戻り値dtypeを指定しない場合は、最初のケースでテスト計算でその値が決定されます。関数が0のようなスカラー整数を返した場合、vectorizeは整数配列を返します。したがって、浮動小数点数が予想される場合は、戻り値dtypeを必ず指定してください。

また、vectorizeは速度ツールではありません。これは、入力にブロードキャストを適用する便利な方法です。あなたの入力を明示的にループするよりもそれほど速くはありません。

np.vectorize(fun, otypes=[float]) 

は、ステップを削除します。

===========

このお試しください:

vfun = np.vectorize(fun, otypes=[float]) 
X = vfun(interval[:,None], pivots, truths) 
print(X.shape)  # (300,3) 
y2 = np.dot(X, coeffs) 
print(y2.shape) # (300,) 

それはvectorize's放送の充実を利用しますが。

私はあなたのfunがが繰り返されることなく、x全体に作用するように書かれていると思われます。 np.maximumを使用するfunを変更

、私は配列x供給することができます:

def fun(x, pivot, truth): 
    if truth: return np.maximum(0, x - pivot) 
    else:  return np.maximum(0, pivot - x) 

をそして、私は、その後のすべてのintervalの値を計算し、pivotstruthsの3例以上のループのみでXを計算することができます一度:

X = np.stack([fun(interval, p, t) for p, t in zip(pivots, truths)], axis=-1) 
y2 = np.dot(X, coeffs) 

3 'の場合'

を適用する別の方法
Xlist = [fun(interval, p, t)*c for p, t, c in zip(pivots, truths, coeffs)] 
y2 = np.sum(Xlist, axis=0) 

np.dot(..., coeffs)はちょうど加重合計です。私はそれが良いのか分からない。

関連する問題