2016-09-27 2 views
4

Q1) Numpy 함수는 다양한 모양의 인수를 사용할 수 있습니다. 예를 들어, np.sum (V)은 아래 두 가지 중 하나를 취할 수 있으며 모양이 다른 출력을 반환 할 수 있습니다.다양한 모양의 인수를 취할 수있는 함수 만들기

x1= np.array([1,3]) #(1) 
x2= np.array([[[1,2],[3,4]], [[5,6],[7,8]]]) #(2) 

나는 두 가지의 길이를 가진 1 차원 벡터에서 두 값을 추가하고 실수를 반환 아래처럼 내 자신의 기능 무언가를 만들고있다.

def foo(V): 
    return V[0]+V[1]; 

그러나이 foo 함수는 하나의 1D 벡터 만 사용할 수 있으며 다른 모양을 사용할 수 없습니다. 위의 x1은 인수로 사용할 수 있지만 x2는 사용할 수 없습니다. 위의 두 변수 (x1과 x2) 중 하나를 사용하여 함수를 작동 시키거나 마지막 치수에서 길이가 2 인 배열을 갖는 다른 셰이프로 작업하려면 foo 함수를 어떻게 수정해야합니까?


--------------------------- 업데이트 --------------- ---------------

내 원래 함수는 하드 코딩 된 음수 가우시안 pdf 함수입니다.

def nGauss(X, mu, cov): 
    # multivariate negative gaussian.  
    # mu is a vector and cov is a covariance matrix. 

    k = X.shape[0]; 
    dev = X-mu 
    p1 = np.power(np.power(np.pi * 2, k) , -0.5); 
    p2 = np.power(np.linalg.det(cov) , -0.5) 
    p3 = np.exp(-0.5 * np.dot(np.dot(dev.transpose(), np.linalg.inv(cov)), dev)); 

    return -1.0 * p1 * p2 * p3; 

이제 그의 함수는 하나의 pdf 값만 반환 할 수 있습니다. 예를 들어 np.array ([1,2])와 같은 인수 만 사용할 수 있지만 np.array와 같은 인수 X를 사용할 수 없습니다 ([[[1,2], [5,6]], [[7,8 ], [9,0]]]). 여기 내 질문에 내 가우스 함수를 임의의 모양의 인수를 사용하는 방법 및 마지막 점을 제외하고 동일한 구조를 유지하는 각 점의 PDF 값을 반환하는 방법이 있었다 nGauss(np.array([1,2]), mu, cov) 반환 [0.000023] 및 nGauss(np.array([[[1,2], [5,6]], [[7,8],[9,0]]]), mu, cov) [[0.000023, 0000014 ], [0.000012, 0.000042]].

scipy 함수 'multivariate_normal.pdf'가이 작업을 수행 할 수 있습니다.


Q2) 는 또한 순이익의 기본 배열을 이해하는데 어려움을 겪고 있어요.

t1=np.array([[1,2,3], [4,5,6]]) 
t2=np.array([1,2,3]) 
t3=np.array([[1,2,3], [4,5,6],5]) 

t1의 모양은 (2,3)이며, 매트릭스 관점에서 볼 때 적합합니다. 2 행 3 열. 그러나 t2의 모양은 (3)이고, 나는 (3)이어야한다고 생각합니다. "3"뒤에 빈 공간의 의미는 무엇입니까? 또한, t3의 형상은 (3,)이다. 이 경우 치수가 다른 빈 공간의 의미는 무엇입니까?

미리 감사드립니다.

+0

'x1'의 경우와'x2'의 경우에 대해 foo 출력의 모양을 어떻게 하시겠습니까? # (2)에 대해 (1)과 (2, 2)에 대해 스칼라를 추측하고 있습니까? 그러나 가장 깊은 차원을 다시 추가하고 있습니까? 수작업으로 수동으로 계산하여 원하는 출력을 게시 할 수 있다면 도움이됩니다. – Praveen

+0

@Praveen 원래 가우스 함수를 업데이트했습니다. 이제는 하나의 벡터를 인수 X로 취할 수 있습니다. 따라서'np.array ([1,2])'를 X로 놓으면 그 시점에서 pdf 값을 얻을 수 있습니다. 이제는 데이터 형식을 허용하고 동일한 구조의 PDF 값을 마지막 차원을 제외한 X 인수로 반환하는 가우스 함수를 만들 수 있는지 궁금합니다. –

답변

1

, 난 당신이 상관없이 배열이 얼마나 많은 크기의, 당신의 배열의 가장 안쪽의 치수를 추가 할 같은데요. 가장 간단한 방법은 ellipsis indexing을 사용하는 것입니다.

>>> a = np.array([1, 2]) 
>>> a[..., 0] + a[..., 1] 
3 

그래서 그냥 foo 정의 : 이것은 1 차원 배열에 대해 동일하게 작동

>>> a = np.arange(24).reshape((3, 4, 2)) 
>>> a 
array([[[ 0, 1], 
     [ 2, 3], 
     [ 4, 5], 
     [ 6, 7]], 

     [[ 8, 9], 
     [10, 11], 
     [12, 13], 
     [14, 15]], 

     [[16, 17], 
     [18, 19], 
     [20, 21], 
     [22, 23]]]) 
>>> a[..., 0] 
array([[ 0, 2, 4, 6], 
     [ 8, 10, 12, 14], 
     [16, 18, 20, 22]]) 
>>> a[..., 1] 
array([[ 1, 3, 5, 7], 
     [ 9, 11, 13, 15], 
     [17, 19, 21, 23]]) 
>>> a[..., 0] + a[..., 1] 
array([[ 1, 5, 9, 13], 
     [17, 21, 25, 29], 
     [33, 37, 41, 45]]) 

: 여기에 대한 자세한 예제 당신의 nGauss 기능을 위해

def foo(V): 
    return V[..., 0] + V[..., 1] 

을의 가장 간단한 해결책은 np.apply_along_axis을 사용하는 것입니다. 예를 들어, 다음과 같이 호출합니다 :

>>> np.apply_along_axis(nGauss, -1, x1, mu, cov) 
+0

정말 고맙습니다. "..."색인 생성은 새로운 것이므로 상세한 예를 들어 설명해 드리겠습니다. Q2와 관련하여 잘못된 방식으로 생각하고 있습니까? –

+0

@AnnDescomp Q2에 대한 대답을 조금 추가 하겠지만 한편으로 hpualj의 대답도 살펴보십시오. 그것은 Q2를 상세하게 묘사하고 좋은 링크를 제공합니다. – Praveen

+0

감사합니다. 이제 그의 링크를 조사하고 있습니다. 또한 원래 함수로 첫 번째 질문을 업데이트합니다. 제 가짜 foo 함수가 원래의 가우스 함수를 대신하는 것은 아닙니다. 추가 입력은 매우 높이 평가 될 것입니다! –

1

Q1 당신 팩 및 인수를 풀 수 :

def foo(*args): 

    result = [] 
    for v in args: 
     result.append(v[0] + v[1]) 

    return result 

이 다음 각 결과의리스트를 돌려, 그 반복, 당신이 원하는대로 당신은 많은 벡터 인수에 전달할 수 있습니다. **로 kwargs를 압축하고 풀 수 있습니다. 여기에 더 많은 정보 : Q1에 대한

https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists

+0

OP는 numpy 배열을 사용하려고합니다. numpy 배열은 압축을 풀 수 없습니다. 가장 바깥 쪽 배열을 목록으로 변환 한 다음 함수에 전달하면 일반적으로 벡터화 된 연산과 관련하여 numpy가 제공하는 이점 대부분을 잃게됩니다. – Praveen

+0

@ZzCalvinzZ 의견을 보내 주셔서 감사합니다! –

2

함수는 두 배열에서 작동합니다

In [1]: def foo(V): 
    ...:  return V[0]+V[1] 
    ...: 
In [2]: foo(np.array([1,3])) 
Out[2]: 4 
In [3]: foo(np.array([[[1,2],[3,4]], [[5,6],[7,8]]])) 
Out[3]: 
array([[ 6, 8], 
     [10, 12]]) 

이 답변이 두 배열의 단지 합계 :

In [4]: np.array([[[1,2],[3,4]], [[5,6],[7,8]]])[0] 
Out[4]: 
array([[1, 2], 
     [3, 4]]) 
In [5]: np.array([[[1,2],[3,4]], [[5,6],[7,8]]])[1] 
Out[5]: 
array([[5, 6], 
     [7, 8]]) 

하는 경우 당신이 뭔가 다른 것을 기대한다면, 우리에게 보여줘야 할 것입니다. 두 번째 질문에 대해서는

:

In [6]: t1=np.array([[1,2,3], [4,5,6]]) 
    ...: t2=np.array([1,2,3]) 
    ...: t3=np.array([[1,2,3], [4,5,6],5]) 
    ...: 
In [7]: t1.shape 
Out[7]: (2, 3) 
In [8]: t2.shape 
Out[8]: (3,) 
In [9]: t3.shape 
Out[9]: (3,) 

(3,)는 1 개 요소 튜플이다. 이 표현들을 비교하십시오.

In [11]: (3) 
Out[11]: 3 
In [12]: (3,) 
Out[12]: (3,) 

(3) V (3,1) 모양의 배열, np.array([[1,2,3]]) V. np.array([1,2,3])에 대한 최근의 여러 문제가 있었다.

t3은 3 개의 요소로 구성된 개체 dtype 배열입니다. 3 개의 입력은 길이가 다르므로 2 차원 배열을 만들 수 없습니다. 지금은이 유형의 어레이에서 멀리 떨어져 있어야합니다. 더 단순한 배열에 집중하십시오. nGauss

In [10]: t3 
Out[10]: array([[1, 2, 3], [4, 5, 6], 5], dtype=object) 
In [13]: t3[0] 
Out[13]: [1, 2, 3] 
In [14]: t3[2] 
Out[14]: 5 

Numpy: Why is difference of a (2,1) array and a vertical matrix slice not a (2,1) array

Difference between single and double bracket Numpy array?

=====================

:

In [53]: mu=np.array([0,0]) 
In [54]: cov=np.eye(2) 
In [55]: xx=np.array([[[1,2], [5,6]], [[7,8],[9,0]]]) 
In [56]: np.apply_along_axis(nGauss, -1, xx, mu, cov) 
Out[56]: 
array([[ -1.30642333e-02, -9.03313360e-15], 
     [ -4.61510838e-26, -4.10103631e-19]]) 

apply_along_axis은 2 번째 희미한 부분을 반복하며 각각 xx[i,j,:] ~ nGauss. 빠르지는 않지만 적용하기가 상대적으로 쉽습니다., 간단한에서

p3 = np.exp(-0.5 * np.dot(np.dot(dev.transpose(), np.linalg.inv(cov)), dev)); 

(2 :

p1 = np.power(np.power(np.pi * 2, k) , -0.5); 

그렇게

p2 = np.power(np.linalg.det(cov) , -0.5) 

는 그래서이 식을 일반화 내려 온다 :

k = X.shape[0]; # I assume you want 
k = X.shape[[1] # the last dimension 
dev = X-mu  # works as long as mu has k terms 

이 는 스칼라) x 케이스, dev은 1d이고 dev.transpose()은 아무 것도 수행하지 않습니다.

einsum을 일반화하는 것이 더 편리합니다. dot; 이전 값을 일치

def nGaussA(X, mu, cov): 
    # multivariate negative gaussian.  
    # mu is a vector and cov is a covariance matrix. 

    k = X.shape[-1]; 
    dev = X-mu 
    p1 = np.power(np.power(np.pi * 2, k) , -0.5); 
    p2 = np.power(np.linalg.det(cov) , -0.5) 
    p3 = np.einsum('...i,ij,...j', dev, np.linalg.inv(cov), dev) 
    p3 = np.exp(-0.5 * p3) 
    return -1.0 * p1 * p2 * p3; 

:

p3 = np.einsum('...i,ij,...j', dev, np.linalg.inv(cov), dev) 

그래서와 : 높은 희미한에

p3 = np.einsum('i,ij,j', dev, np.linalg.inv(cov), dev) 

일반화로 단순화

p3 = np.einsum('j,j', np.einsum('i,ij', dev, np.linalg.inv(cov)), dev) 
p3 = np.exp(-0.5 * p3) 

: 나는 해당이 생각

In [85]: nGaussA(x,mu,cov) 
Out[85]: -0.013064233284684921 
In [86]: nGaussA(xx,mu,cov) 
Out[86]: 
array([[ -1.30642333e-02, -9.03313360e-15], 
     [ -4.61510838e-26, -4.10103631e-19]]) 

따라서 함수를 일반화하는 방법은 각 단계를 확인하는 것입니다. 스칼라가 생성되면 보관하십시오. x과 함께 작동하는 경우 보관하십시오. 그러나 다른 배열과 차원을 조정해야하는 경우이를 수행하는 numpy 작업을 사용하십시오. 흔히 방송과 관련이 있습니다. 때로는 다른 numpy 함수를 일반화하는 방법을 연구하는 데 도움이됩니다 (예 : apply_along_axis, apply_over_axes, cross 등).

대화 형 numpy 세션은 필수적입니다. 작은 샘플 배열로 아이디어를 시도 할 수있게 해줍니다.

+0

답변 해 주셔서 감사합니다. 신비한 배열을 이해하는 데 정말로 도움이됩니다. 한편, 이제 막 업데이트 한 원래 함수를 게시해야한다는 것을 알았습니다. 나는 (n,) 모양으로 하나의 np.array를 취하는 부정적인 가우스 pdf 함수를 작성했습니다. 따라서 np.array ([1,2])와 같은 인수 만 사용할 수 있지만 np.array ([[[1,2], [5,6]], [7,8], [ 9,0]]]). 여기 내 질문은 내 가우스 함수를 임의의 모양의 인수를 사용하여 동일한 구조를 유지하는 각 점의 pdf 값을 반환하는 방법이었습니다. –

+0

두 개의'점 '제품을 일반화하기 위해'einsum'을 사용하여'nGauss'의 일반화 작업을했습니다. – hpaulj

관련 문제