2011-12-26 7 views
3

에 내가 공학 학생이고 내가 포트란 코드를 작성하는 것이 익숙 해요 반복,하지만 지금은 NumPy와를 사용하여 내 수치 조리법 파이썬에 더 얻기 위해 노력하고있어.더 파이썬 방법은 NumPy와

내가 여러 배열에서 요소를 사용하여 반복 계산을 수행하는 데 필요한 경우, 내가 포트란 쓸 줄 것과 즉각적인 번역

k = np.zeros(N, dtype=np.float) 
u = ... 
M = ... 
r = ... 
for i in xrange(N): 
    k[i] = ... # Something with u[i], M[i], r[i] and r[i - 1], for example 

것이다 그러나이 방법은 더 파이썬 있는지 궁금했다, 또는 어떤 방법보다 더 낫다 : 나는 그것을 필요하지 않은 경우,

for i, (k_i, u_i, M_i, r_i) in enumerate(zip(k, u, M, r)): 
    k_i = ... # Something with u_i, M_i, r_i and r[i - 1] 

덕분에 나는 인덱스가 열거 할 그렇지 않으면 난 그냥 지퍼 또는 itertools.izip 사용할 수 있습니다.

아이디어가 있으십니까? 성능면에서 코드가 어떻게 영향을 줍니까? 이 작업을 수행 할 수있는 다른 방법이 있습니까?

답변

-1

나는 두 배열을 곱하면 목록 또는 발전기를 돌려줍니다 지능형리스트를 map

map(lambda x, y : x*y , zip(some_array, some_other_array)) 

같은

k = [ x ** y for x, y in zip(some_array, some_other_array) ] 

다른 사람을 좋아한다. (물론 numpy로 특정 작업을 수행하는 다른 방법이 있습니다.) 배열로 다시 변환하려면

k = array ([x ** y for zip (some_array, some_other_array)])

+0

사실,이 방법을 사용하면 이전 요소를 복구 할 수 없습니다 (예를 들어, 나와있는 것처럼 열거 형을 사용하는 이유입니다). – astrojuanlu

+0

꽤 옳습니다. 시퀀스 작업을 복잡하게 할 때 종종 결과를 명시 적으로 생성하는 독립형 함수 생성기를 작성합니다. 원한다면 내 호출 코드를 numpy 배열로 묶을 수 있습니다. –

+0

-1, numpy에서 선호하는 방법은 요소 단위의 작업이기 때문입니다. 답을보십시오 unutbu – bmu

7

거의 NumPy와 연산 소자 와이즈 행한다. 그래서 대신 명시 루프를 작성 배열 기반 식 사용 k을 한정하려고 대신, 예를 들어

r_shifted = np.roll(x, shift = 1) 
k = ... # some formula in terms of u, M, r, r_shifted 

import numpy as np 

N=5 
k = np.zeros(N, dtype=np.float) 
u = np.ones(N, dtype=np.float) 
M = np.ones(N, dtype=np.float) 
r = np.ones(N, dtype=np.float) 
for i in xrange(N): 
    k[i] = u[i] + M[i] + r[i] + r[i-1] 
print(k) 
# [ 4. 4. 4. 4. 4.] 

사용 :

r_shifted = np.roll(r, shift = 1) 
k = u + M + r + r_shifted 
print(k) 
# [ 4. 4. 4. 4. 4.] 

np.roll(r, shift = 1)과 함께 같은 크기의 새로운 배열을 r과 함께 반환합니다. i = 0, ..., N-1에 대해서는입니다.

In [31]: x = np.arange(5) 

In [32]: x 
Out[32]: array([0, 1, 2, 3, 4]) 

In [33]: np.roll(x, shift = 1) 
Out[33]: array([4, 0, 1, 2, 3]) 

이 같은 사본 (r 같은 크기의) 더 많은 메모리를 필요로하지만, 대신 느린 파이썬 루프를 사용하는 빠른 NumPy와의 작업을 수행 할 수 있습니다 만들기.


때때로 k 대한 공식 대신 r[:-1]r[1:]의 관점에서 정의 될 수있다. r[:-1]r[1:]r과 같은 모양의 조각입니다 있습니다. r의 기본 조각이r전망이 아닌 사본을 소위 때문에 이 경우, 당신은 어떤 여분의 메모리가 필요하지 않습니다.

다음 k 길이 N-1 대신 N을했을 것 때문에 위의 예에서이 방법 k를 정의하지 않았다, 그래서 원래의 코드가 생산 한 것보다 약간 달라졌을 것이다.

+0

실제로 계산에 필요한 수식을 쓰는 것이 항상 가능하지는 않습니다. 복잡한 연산이 필요할 수도 있고 배열을 0으로 초기화하고 일부 외부 값을 사용하여 연속적인 접근을 수행 할 수도 있습니다. 예를 들어, ODE를 해결하려고 할 때도 마찬가지입니다. 어쨌든, np.roll() 팁 주셔서 감사합니다! – astrojuanlu

+1

사실. 파이썬 루프를 피하기 위해 numpy-base 함수 나 표현식이 없다면 [Cython] (http://cython.org/)에서 루프를 다시 작성해보십시오 ("Cython으로 빠른 수치 계산"참조) [600K PDF] (http://conference.scipy.org/proceedings/SciPy2009/paper_2/full_text.pdf)). – unutbu

+0

[F2py] (http://www.scipy.org/F2py)도 있습니다.이 기능을 사용하면 Python에서 Fortran 기능을 호출 할 수 있습니다. 그렇다면 코드를 전혀 번역 할 필요가 없습니다. – unutbu