2017-10-08 9 views
0

は、同じ行を持ちますが順序が違う2つのnumpy ndarraysです。関数g1を行単位で適用すると、同じ結果が別の順序で返されることが予想されます。しかし、そうではありません。numpy apply_along_axisが機能しないのはなぜですか?

g1(x): 
    return max(0, (x[0] - 1)**2 + (x[1] - 1)**2 - 1.05**2) 

Case1: 
sol1 = np.array(
     [ 
      [0, 0], 
      [1, 1], 
      [0, 1], 
      [1, 0], 
      [0.2, 0.7], 
      [0.5, 0.5], 
      [0.75, 0], 
      [0.25, 0.8], 
      [0.5, 0.6], 
      [0.2, 0.7], 
     ] 
) 
v = numpy.apply_along_axis(g1, 1, sol1) 

This produce: [ 0.8975, 0., 0., 0., 0., 0., 0., 0., 0., 0.] as expected. 
Case2: 
# The same array with rows shuffled. 
sols = numpy.array(
     [ 
      [0, 1], 
      [0.2, 0.7], 
      [0.5, 0.5], 
      [0.75, 0], 
      [0.2, 0.7], 
      [1, 0], 
      [0.25, 0.8], 
      [0.5, 0.6], 
      [0, 0], 
      [1, 1], 
     ] 
) 
v = numpy.apply_along_axis(g1, 1, sols) 
This produces: [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.] which is wrong. 
Should be: [ 0., 0., 0., 0., 0., 0., 0., 0., 0.8975, 0.] 

私のシステムでは、次のとおりです。 numpyの:1.13.1: のpython:3.6.2: Win10プロ: conda:あなたの計算を再作成4.3.27

おかげ

+0

すなわち、 '(0.0、...)最大' のすべてのケースでfloatを返す試してみてください。 – hpaulj

+0

これは両方のケースでうまくいきました。ありがとうございました。私はちょうどそれがすべての違いを作った理由を理解しようとしています – Christie

答えて

2

In [25]: def g1(x): 
    ...:  return max(0, (x[0] - 1)**2 + (x[1] - 1)**2 - 1.05**2) 
    ...: 
In [26]: g1([0,0]) 
Out[26]: 0.8975 
In [27]: g1([1,1]) 
Out[27]: 0 
In [28]: np.apply_along_axis(g1,1,[[0,0],[1,1]]) 
Out[28]: array([ 0.8975, 0. ]) 
In [29]: np.apply_along_axis(g1,1,[[1,1],[0,0],[1,1]]) 
Out[29]: array([0, 0, 0]) 

Out[29]は整数配列であり、記述する浮動小数点数ではありません(t帽子はコピーアンドペーストではない?)。

apply_along_axisは、リターンdtypeを決定するための試算を使用します。最初のcaseが整数を返す場合、結果を取得する整数配列を作成します。 floatを整数配列に代入すると、切り捨てられます。

私はこの問題をnp.vectorizeと見ており、ここでも起こっていると思われます。 apply_along_axisのコードを見て、どこでどのように起きているのかを確認できます。

したがって、g1max(0.0, ...)に変更すると、関数は必ずfloatを返し、applyは正しいdtypeを返します。


コードの関連作品:

res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs)) 

# build a buffer for storing evaluations of func1d. 
# remove the requested axis, and add the new ones on the end. 
# laid out so that each write is contiguous. 
# for a tuple index inds, buff[inds] = func1d(inarr_view[inds]) 
buff = zeros(inarr_view.shape[:-1] + res.shape, res.dtype) 
+0

偉大な、説明のためのthx。それはかなり微妙であり、確かにいくつかの問題を引き起こす可能性があります。私はこれからもっと勤勉になるでしょう。 – Christie

関連する問題