νƒœκ·Έ 보관물: python

python

numpy slicesλ₯Ό μ‚¬μš©ν•˜μ—¬μ΄ λ³΅μž‘ν•œ ν‘œν˜„μ„ ν‘œν˜„ν•˜λŠ” 방법 λŠ” 크기의

νŒŒμ΄μ¬μ—μ„œ

μ—¬κΈ°μ„œ 와 λŠ” 크기의 numpy λ°°μ—΄ 이며 크기의 numpy λ°°μ—΄μž…λ‹ˆλ‹€ . 크기 은 μ΅œλŒ€ μ•½ 10000 일 수 있으며이 ν•¨μˆ˜λŠ” μ—¬λŸ¬ 번 평가 될 λ‚΄λΆ€ λ£¨ν”„μ˜ μΌλΆ€μ΄λ―€λ‘œ 속도가 μ€‘μš”ν•©λ‹ˆλ‹€.

μ—‘μŠ€λ‚˜λŠ”=βˆ‘μ œμ΄=1λ‚˜λŠ”βˆ’1μΌ€μ΄λ‚˜λŠ”βˆ’μ œμ΄,μ œμ΄γ…λ‚˜λŠ”βˆ’μ œμ΄γ…μ œμ΄,

μ—‘μŠ€

와이

μ—”

케이

μ—”Γ—μ—”

μ—”

μ΄μƒμ μœΌλ‘œλŠ” for 루프λ₯Ό ν”Όν•˜κ³  μ‹Άμ§€λ§Œ 세상에 끝이 μ—†λ‹€λ©΄ μ„Έκ³„μ˜ 끝이 μ•„λ‹ˆλΌκ³  μƒκ°ν•©λ‹ˆλ‹€. λ¬Έμ œλŠ” λͺ‡ 개의 쀑첩 루프λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  μ–΄λ–»κ²Œ ν•΄μ•Όν•˜λŠ”μ§€ μ•Œμ§€ λͺ»ν•œλ‹€λŠ” κ²ƒμ΄λ―€λ‘œ λ‹€μ†Œ 느렀질 수 μžˆμŠ΅λ‹ˆλ‹€.

λˆ„κ΅¬λ“ μ§€ 효율적이고 읽기 μ‰¬μš΄ λ°©μ‹μœΌλ‘œ numpyλ₯Ό μ‚¬μš©ν•˜μ—¬ μœ„μ˜ 방정식을 ν‘œν˜„ν•˜λŠ” 방법을 λ³Ό 수 μžˆμŠ΅λ‹ˆκΉŒ? 더 일반적으둜, 이런 μ’…λ₯˜μ˜ 것에 μ ‘κ·Όν•˜λŠ” κ°€μž₯ 쒋은 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?



λ‹΅λ³€

μ—¬κΈ° Numba μ†”λ£¨μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€. λ‚΄ μ»΄ν“¨ν„°μ—μ„œ Numba 버전은 λ°μ½”λ ˆμ΄ν„°κ°€μ—†λŠ” 파이썬 버전보닀 1000 λ°° 이상 λΉ λ¦…λ‹ˆλ‹€ (200Γ—200 맀트릭슀 β€˜k’및 200 길이 벑터 β€˜a’). λ˜ν•œ 호좜 λ‹Ή μ•½ 10 마이크둜 초λ₯Ό μΆ”κ°€ν•˜λŠ” @autojit λ°μ½”λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μΌν•œ μ½”λ“œκ°€ μ—¬λŸ¬ μœ ν˜•μ—μ„œ μž‘λ™ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

from numba import jit, autojit

@jit('f8[:](f8[:,:],f8[:])')
#@autojit
def looped_ver(k, a):
    x = np.empty_like(a)
    for i in range(x.size):
        sm = 0.0
        for j in range(0, i+1):
            sm += k[i-j,j] * a[i-j] * a[j]
        x[i] = sm
    return x

곡개 : μ €λŠ” Numba 개발자 쀑 ν•œ λͺ…μž…λ‹ˆλ‹€.


λ‹΅λ³€

여기에 μ‹œμž‘μ΄ μžˆμŠ΅λ‹ˆλ‹€. 첫째, μ‹€μˆ˜μ— λŒ€ν•΄ μ‚¬κ³Όλ“œλ¦½λ‹ˆλ‹€.

λ‚˜λŠ” 두 κ°€μ§€ λ‹€λ₯Έ μ ‘κ·Ό λ°©μ‹μœΌλ‘œ μ‹€ν—˜ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 합계에 λŒ€ν•œ ν•œκ³„μ— μ•½κ°„ ν˜Όλž€ μŠ€λŸ¬μ› λ‹€. μ•„λ‹ˆλΌ μƒν•œμ΄ 이어야 ν•˜λŠ”κ°€?

λ‚˜λŠ”

λ‚˜λŠ”βˆ’1

νŽΈμ§‘ : μ•„λ‹ˆμ˜€, μ§ˆλ¬Έμ— 제곡된 μƒν•œμ΄ μ •ν™•ν–ˆμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ 닡변이 λ™μΌν•œ μ½”λ“œλ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— 여기에 κ·ΈλŒ€λ‘œ λ‘μ—ˆμ§€λ§Œ ν•΄κ²° 방법은 κ°„λ‹¨ν•©λ‹ˆλ‹€.

λ¨Όμ € 반볡 버전 :

def looped_ver(k, a):
    x = np.empty_like(a)
    for i in range(x.size):
        sm = 0
        for j in range(0, i+1):
            sm += k[i-j,j] * a[i-j] * a[j]
        x[i] = sm
    return x

λ‚˜λŠ” 그것을 numpy 슬라이슀둜 단일 λ£¨ν”„λ‘œ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

def vectorized_ver(k, a):
    ktr = zeros_like(k)
    ar = zeros_like(k)
    sz = len(a)
    for i in range(sz):
        ktr[i,:i+1] = k[::-1].diagonal(-sz+i+1)
        a_ = a[:i+1]
        ar[i,:i+1] = a_[::-1] * a_
    return np.sum(ktr * ar, 1)

λ•Œ λͺ…μ‹œ 적 루프가 ν•˜λ‚˜ 인 numpy 버전은 λ‚΄ μ»΄ν“¨ν„°μ—μ„œ μ•½ 25 λ°° λΉ λ¦…λ‹ˆλ‹€ .

μ—”=5000

그런 λ‹€μŒ (더 읽기 μ‰¬μš΄) 반볡 μ½”λ“œμ˜ Cython 버전을 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

import numpy as np
import cython
cimport numpy as np

@cython.boundscheck(False)
@cython.wraparound(False)
def cyth_ver(double [:, ::1] k not None,
              double [:] a not None):
    cdef double[:] x = np.empty_like(a)
    cdef double sm
    cdef int i, j

    for i in range(len(a)):
        sm = 0.0
        for j in range(i+1):
            sm = sm + k[i-j,j] * a[i-j] * a[j]
        x[i] = sm
    return x

λ‚΄ λ…ΈνŠΈλΆμ—μ„œ 이것은 루프 버전보닀 μ•½ 200 λ°° λΉ λ₯΄λ©° (1 루프 벑터화 버전보닀 8 λ°° λΉ λ¦…λ‹ˆλ‹€). λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ 더 μž˜ν•  수 μžˆλ‹€κ³  ν™•μ‹ ν•©λ‹ˆλ‹€.

λ‚˜λŠ” Julia 버전을 κ°€μ§€κ³  λ†€μ•˜μœΌλ©° Cython μ½”λ“œμ™€ λΉ„μŠ·ν•œ κ²ƒμœΌλ‘œ λ³΄μ˜€μŠ΅λ‹ˆλ‹€.


λ‹΅λ³€

당신이 μ›ν•˜λŠ” 것은 컨볼 λ£¨μ…˜ 인 것 κ°™μŠ΅λ‹ˆλ‹€. 그것을 λ‹¬μ„±ν•˜λŠ” κ°€μž₯ λΉ λ₯Έ 방법은 numpy.convolveκΈ°λŠ₯ 이라고 μƒκ°ν•©λ‹ˆλ‹€ .

μ •ν™•ν•œ μš”κ΅¬μ— 따라 색인을 μˆ˜μ •ν•΄μ•Ό ν•  μˆ˜λ„ μžˆμ§€λ§Œ λ‹€μŒκ³Ό 같이 μ‹œλ„ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

import numpy as np
a = [1, 2, 3, 4, 5]
k = [2, 4, 6, 8, 10]

result = np.convolve(a, k*a[::-1])

λ‹΅λ³€


이 글은 scicomp μΉ΄ν…Œκ³ λ¦¬μ— λΆ„λ₯˜λ˜μ—ˆκ³  , νƒœκ·Έκ°€ 있으며 λ‹˜μ— μ˜ν•΄ 에 μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.