2017-10-08 2 views
0

은 동일한 행을 갖지만 다른 순서로 두 개의 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 : 파이썬 : 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]은 정수 배열이며 사용자가 설명하는 float가 아닙니다 (t 모자는 복사 - 붙여 넣기가 아닌가?).

apply_along_axis은 return dtype을 결정하기 위해 평가판 계산을 사용합니다. 첫 번째 경우가 정수를 반환하면 결과를 얻기 위해 정수 배열을 만듭니다. 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

관련 문제