Numpy: 0이 μ•„λ‹Œ 첫 번째 μš”μ†Œ(Trac #1673)

에 λ§Œλ“  2012λ…„ 10μ›” 20일  Β·  26μ½”λ©˜νŠΈ  Β·  좜처: numpy/numpy

_trac μ‚¬μš©μž tom3118이 2010-11-13에 원본 ν‹°μΌ“ http://projects.scipy.org/numpy/ticket/1673 , unknown에 ν• λ‹Ήν–ˆμŠ΅λ‹ˆλ‹€._

"matlab μ‚¬μš©μžλ₯Ό μœ„ν•œ numpy"λŠ” λ‹€μŒμ„ μ‚¬μš©ν•  것을 μ œμ•ˆν•©λ‹ˆλ‹€.
nonzero(A)[0][0]
λ°°μ—΄ A의 0이 μ•„λ‹Œ 첫 번째 μš”μ†Œμ˜ 인덱슀λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.

μ΄κ²ƒμ˜ λ¬Έμ œλŠ” Aκ°€ 백만 개의 μš”μ†Œ 길이가 될 수 있고 첫 번째 μš”μ†Œκ°€ 0일 수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

이것은 맀우 일반적인 μž‘μ—…μž…λ‹ˆλ‹€. 이λ₯Ό μœ„ν•œ 효율적인 λ‚΄μž₯ 방법이 맀우 μœ μš©ν•  κ²ƒμž…λ‹ˆλ‹€. λ˜ν•œ find κ°€ 일반적인 Matlabμ—μ„œ μ‚¬λžŒλ“€μ΄ μ‰½κ²Œ μ „ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

01 - Enhancement Other

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‚˜λŠ” 이것이 3 λ…„ λŠ¦μ—ˆλ‹€λŠ” 것을 μ•Œκ³  μžˆμ§€λ§Œ 이것이 μ§€κΈˆ numpy에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆκΉŒ? Matlab λ°°κ²½μ—μ„œ λ‚˜μ˜¨ 이 κΈ°λŠ₯은 μ €μ—κ²Œ 정말 μ€‘μš”ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. PR은 높이 평가될 κ²ƒμž…λ‹ˆλ‹€(μž„μ‹œ 개발자 쀑 ν•œ λͺ…이 μ•„λ‹˜).

λͺ¨λ“  26 λŒ“κΈ€

_trac μ‚¬μš©μž tom3118이 2010-11-13에 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€_

κ΄€λ ¨ μ‚¬μš© μ‚¬λ‘€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
filter(test,A)[0]
A κ°€ κΈΈκ±°λ‚˜ test κ°€ λΉ„μŒ‰λ‹ˆλ‹€.

__@rgommers λŠ” 2011-03-24에 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

0이 μ•„λ‹Œ 첫 번째 값일 ν•„μš”λŠ” μ—†μœΌλ©° λ¨Όμ € λͺ¨λ“  값이 μœ μš©ν•  κ²ƒμž…λ‹ˆλ‹€.

__@rgommers λŠ” 2011-03-24에 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

#2333μ—μ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄ 1-D에 λŒ€ν•œ μ˜λ―ΈλŠ” λͺ…ν™•ν•©λ‹ˆλ‹€. >1-D의 경우 의미둠이 λ…Όμ˜ λŒ€μƒμž…λ‹ˆλ‹€.

μ•„λ§ˆλ„ 좕에 λŒ€ν•œ 반볡 μˆœμ„œλ₯Ό κ²°μ •ν•˜λŠ” ν‚€μ›Œλ“œκ°€ μž‘λ™ν•  κ²ƒμž…λ‹ˆλ‹€. λ˜λŠ” >1-D에 λŒ€ν•΄ λ‹¨μˆœνžˆ μ •μ˜λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

_trac μ‚¬μš©μž lcampagn이 2011-07-09에 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

numpyμ—μ„œ find_first에 λŒ€ν•œ λ§Žμ€ μš”μ²­μ„ λ³΄μ•˜μ§€λ§Œ μ΄λŸ¬ν•œ μš”μ²­μ˜ λŒ€λΆ€λΆ„μ€ "x보닀 μž‘μ€ 첫 번째 κ°’ μ°ΎκΈ°" λ˜λŠ” "0이 μ•„λ‹Œ 첫 번째 κ°’ μ°ΎκΈ°"와 같이 λ―Έλ¬˜ν•˜κ²Œ λ‹€λ₯Έ(ν˜Έν™˜λ˜μ§€ μ•ŠλŠ”) μš”κ΅¬ 사항이 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒ κΈ°λŠ₯ 사양을 μ œμ•ˆν•©λ‹ˆλ‹€.

  ind = array.find(x, testOp='eq', arrayOp='all', axis=0, test=None)
  arguments:
    x       -> value to search for
    testOp  -> condition to test for ('eq', 'ne', 'gt', 'lt', 'ge', 'le')
    arrayOp -> method for joining multiple comparisons ('any' or 'all')
    axis    -> the axis over which to search
    test    -> for convenience, this may specify a function to call to perform
               the test. This is not expected to be efficient.
  returns: 
    first index where condition is true (or test returns true, if given)
    or None if the condition was never met

μ–΄λ ˆμ΄κ°€ ndim > 1이면 일반 λΈŒλ‘œλ“œμΊμŠ€νŒ… κ·œμΉ™μ„ μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈκ°€ μˆ˜ν–‰λ©λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄ λͺ¨μ–‘이 (2,3)인 배열이 μžˆλŠ” 경우 λ‹€μŒμ΄ μœ νš¨ν•©λ‹ˆλ‹€.

  ## find first row with all values=0
  array.find(0, testOp='eq', arrayOp='all', axis=0)
  ## equivalent to:
  for i in range(array.shape[axis]):
    if (array[i] == 0).all():
      return i

  ## find first column with any element greater than its corresponding element in col
  col = array([1,2])
  array.find(col, testOp='gt', arrayOp='any', axis=1)
  ## equivalent to:
  for i in range(array.shape[axis]):
    if (array[:,i] == col.any():
      return i

μš”μ „μ— 이 κΈ°λŠ₯이 ν•„μš”ν–ˆκΈ° λ•Œλ¬Έμ— 이에 λŒ€ν•΄ 잘 μ‚΄νŽ΄λ³΄μ•˜κ³  μ μ ˆν•˜κ²Œ λΉ λ₯Έ κ²°κ³Όλ₯Ό μ–»μœΌλ €λ©΄ C μ†”λ£¨μ…˜μ΄ ν•„μš”ν•˜λ‹€κ³  ν™•μ‹ ν–ˆμ§€λ§Œ 파이썬으둜 μž‘μ„±λœ 청크 μ ‘κ·Ό 방식은 μ μ ˆν•˜κ²Œ λΉ λ₯΄κ³  λ§Žμ€ λ‚΄ κ²½μš°μ—λŠ” λΆ€νŒ…ν•˜κΈ°μ— 더 μœ μ—°ν•©λ‹ˆλ‹€.

import numpy as np
from itertools import chain, izip


def find(a, predicate, chunk_size=1024):
    """
    Find the indices of array elements that match the predicate.

    Parameters
    ----------
    a : array_like
        Input data, must be 1D.

    predicate : function
        A function which operates on sections of the given array, returning
        element-wise True or False for each data value.

    chunk_size : integer
        The length of the chunks to use when searching for matching indices.
        For high probability predicates, a smaller number will make this
        function quicker, similarly choose a larger number for low
        probabilities.

    Returns
    -------
    index_generator : generator
        A generator of (indices, data value) tuples which make the predicate
        True.

    See Also
    --------
    where, nonzero

    Notes
    -----
    This function is best used for finding the first, or first few, data values
    which match the predicate.

    Examples
    --------
    >>> a = np.sin(np.linspace(0, np.pi, 200))
    >>> result = find(a, lambda arr: arr > 0.9)
    >>> next(result)
    ((71, ), 0.900479032457)
    >>> np.where(a > 0.9)[0][0]
    71


    """
    if a.ndim != 1:
        raise ValueError('The array must be 1D, not {}.'.format(a.ndim))

    i0 = 0
    chunk_inds = chain(xrange(chunk_size, a.size, chunk_size), 
                 [None])

    for i1 in chunk_inds:
        chunk = a[i0:i1]
        for inds in izip(*predicate(chunk).nonzero()):
            yield (inds[0] + i0, ), chunk[inds]
        i0 = i1
In [1]: from np_utils import find

In [2]: import numpy as np

In [3]: import numpy.random    

In [4]: np.random.seed(1)

In [5]: a = np.random.randn(1e8)

In [6]: a.min(), a.max()
Out[6]: (-6.1194900990552776, 5.9632246301166321)

In [7]: next(find(a, lambda a: np.abs(a) > 6))
Out[7]: ((33105441,), -6.1194900990552776)

In [8]: (np.abs(a) > 6).nonzero()
Out[8]: (array([33105441]),)

In [9]: %timeit (np.abs(a) > 6).nonzero()
1 loops, best of 3: 1.51 s per loop

In [10]: %timeit next(find(a, lambda a: np.abs(a) > 6))
1 loops, best of 3: 912 ms per loop

In [11]: %timeit next(find(a, lambda a: np.abs(a) > 6, chunk_size=100000))
1 loops, best of 3: 470 ms per loop

In [12]: %timeit next(find(a, lambda a: np.abs(a) > 6, chunk_size=1000000))
1 loops, best of 3: 483 ms per loop

λ‚˜λŠ” 이것을 개발자 메일링 λ¦¬μŠ€νŠΈμ— 올릴 κ²ƒμ΄μ§€λ§Œ, μΆ©λΆ„ν•œ 관심이 μžˆλ‹€λ©΄ 그것을 PR둜 λ°”κΏ€ 만큼 μΆ©λΆ„νžˆ 기쁠 κ²ƒμž…λ‹ˆλ‹€.

건배,

λ‚˜λŠ” 이것이 3 λ…„ λŠ¦μ—ˆλ‹€λŠ” 것을 μ•Œκ³  μžˆμ§€λ§Œ 이것이 μ§€κΈˆ numpy에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆκΉŒ? Matlab λ°°κ²½μ—μ„œ λ‚˜μ˜¨ 이 κΈ°λŠ₯은 μ €μ—κ²Œ 정말 μ€‘μš”ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. PR은 높이 평가될 κ²ƒμž…λ‹ˆλ‹€(μž„μ‹œ 개발자 쀑 ν•œ λͺ…이 μ•„λ‹˜).

λ‚˜λ„ 이것에 관심이 μžˆμ„ 것이닀.

μ–΄μ©Œλ©΄ λ‹Ήμ—°ν•˜μ§€λ§Œ μ–ΈκΈ‰λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— np.all() 및 np.any() λŠ” 게으λ₯΄κ²Œ λ§Œλ“œλŠ” 것이 훨씬 더 μ‰¬μšΈ κ²ƒμž…λ‹ˆλ‹€(차원 > 1의 경우 λͺ¨ν˜Έν•˜μ§€ μ•ŠμŒ). ν˜„μž¬...

In [2]: zz = np.zeros(shape=10000000)

In [3]: zz[0] = 1

In [4]: %timeit -r 1 -n 1 any(zz)
1 loop, best of 1: 3.52 Β΅s per loop

In [5]: %timeit -r 1 -n 1 np.any(zz)
1 loop, best of 1: 16.7 ms per loop

(μ£„μ†‘ν•©λ‹ˆλ‹€. #3446에 λŒ€ν•œ μ°Έμ‘°λ₯Ό λ†“μ³€μŠ΅λ‹ˆλ‹€.)

λ‚˜λŠ” κ½€ μ˜€λž«λ™μ•ˆ 이 문제의 효율적인 μ†”λ£¨μ…˜μ„ μ°Ύκ³  μžˆμ—ˆκ³  이 κΈ°λŠ₯을 지원할 ꡬ체적인 κ³„νšμ΄ μ—†λŠ” 것 κ°™μ•„μ„œ apiκ°€ μ œμ•ˆν•œ κ²ƒμ²˜λŸΌ μ™„μ „ν•˜μ§€ μ•Šκ³  λ‹€μš©λ„κ°€ μ•„λ‹Œ μ†”λ£¨μ…˜μ„ 찾으렀고 λ…Έλ ₯ν–ˆμŠ΅λ‹ˆλ‹€. μœ„μ—μ„œ (특히 ν˜„μž¬λ‘œμ„œλŠ” 1D λ°°μ—΄λ§Œ 지원함) C둜 μ™„μ „νžˆ μž‘μ„±λœλ‹€λŠ” 이점이 μžˆμœΌλ―€λ‘œ 였히렀 효율적으둜 λ³΄μž…λ‹ˆλ‹€.

μΆœμ²˜μ™€ μ„ΈλΆ€ μ •λ³΄λŠ” λ‹€μŒμ—μ„œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.

https://pypi.python.org/pypi?name=py_find_1st& :action=display

κ΅¬ν˜„μ— λŒ€ν•œ λͺ¨λ“  의견, 특히 λΆ€μšΈ 배열을 μ „λ‹¬ν•˜κ³  ν•΄λ‹Ή PyPi νŽ˜μ΄μ§€μ— μ„€λͺ…λœ 첫 번째 μ°Έ 값을 검색할 λ•Œ λ‹€μ†Œ λ†€λΌμš΄ μ„±λŠ₯ λ¬Έμ œμ— λŒ€ν•œ μ§ˆλ¬Έμ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

70,000번 이상 쑰회된 이 κΈ°λŠ₯을 μ°Ύκ³  μžˆλŠ” stackexchange κ²Œμ‹œλ¬Ό μ—μ„œ 이것을 μ°Ύμ•˜μŠ΅λ‹ˆλ‹€. @roebel 이에 λŒ€ν•œ ν”Όλ“œλ°±μ„ 받은 적이 μžˆμŠ΅λ‹ˆκΉŒ? 더 λ§Žμ€ 관심을 끌 수 μžˆλŠ” κΈ°λŠ₯에 λŒ€ν•œ PR을 넣을 수 μžˆμŠ΅λ‹ˆκΉŒ?

ν”Όλ“œλ°±μ„ 받은 적은 μ—†μ§€λ§Œ λͺ‡λͺ‡ μ‚¬λžŒλ“€μ€ λΆ„λͺ…νžˆ 문제 없이 νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.
BTW, λ‚˜λŠ” μ•„λ‚˜μ½˜λ‹€ μ„€μΉ˜ ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

https://anaconda.org/roebel/py_find_1st

PRκ³Ό κ΄€λ ¨ν•˜μ—¬ numpy에 μ‰½κ²Œ 병합될 수 μžˆλ„λ‘ 이λ₯Ό μ‘°μ •ν•˜λŠ” 데 ν•„μš”ν•œ λ…Έλ ₯을 쑰사해야 ν•©λ‹ˆλ‹€. API λ³€κ²½ 및 ν™•μž₯에 λŒ€ν•΄ ν† λ‘ ν•  μ‹œκ°„μ΄ μ—†μŠ΅λ‹ˆλ‹€.

" priority:normal "을 μ œκ±°ν•˜λ©΄ 이 μ€‘μš”ν•œ κΈ°λŠ₯에 λŒ€ν•œ 관심이 μ€„μ–΄λ“€κΉŒμš”?

μš°μ„  μˆœμœ„λŠ” λ ˆμ΄λΈ” 없이 μ—¬μ „νžˆ "보톡"μž…λ‹ˆλ‹€. 이 λ¬Έμ œλŠ” μ‹€μ œλ‘œ PR을 λ§Œλ“€κ³  λ¬Έμ„œν™” 및 벀치마크λ₯Ό ν¬ν•¨ν•œ 승인 ν”„λ‘œμ„ΈμŠ€λ₯Ό 톡해 ν‘Έμ‹œν•  챔피언이 ν•„μš”ν•©λ‹ˆλ‹€.

λͺ…λͺ©μƒ all_equal μ •λ„μ΄μ§€λ§Œ μ΄κ²ƒμ˜ 일뢀λ₯Ό κ΅¬ν˜„ν•˜λŠ” κ²ƒμœΌλ‘œ λ³Ό 수 μžˆλŠ” #8528을 κ°€λ¦¬ν‚€λŠ” 것이 μ—¬κΈ°μ—μ„œ μœ μš©ν•  κ²ƒμž…λ‹ˆλ‹€. μ‹€μ œλ‘œ https://github.com/numpy/numpy/pull/8528#issuecomment -365358119μ—μ„œ @ahaldane 은 μƒˆλ‘œμš΄ gufunc all_equal λŒ€μ‹  λͺ¨λ“  비ꡐ μ—°μ‚°μžμ— first κ°μ†Œ 방법을 κ΅¬ν˜„ν•˜λŠ” 것을 λͺ…μ‹œμ μœΌλ‘œ μ œμ•ˆν•©λ‹ˆλ‹€. all_equal .

이것은 λ˜ν•œ μƒλ‹Ήν•œ μ–‘μ˜ κ΅¬ν˜„μ΄ μ μ‘λ˜κΈ°λ₯Ό 기닀리고 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€(gufuncμ—μ„œ μƒˆλ‘œμš΄ μΆ•μ†Œ λ°©λ²•μœΌλ‘œμ˜ μ‚¬μ†Œν•œ 변경은 μ•„λ‹ˆλ©° λͺ¨λ“  ufunc에 λŒ€ν•œ μƒˆλ‘œμš΄ 방법을 μ›ν•˜λŠ”μ§€ 여뢀에 λŒ€ν•œ 질문이 μžˆμŠ΅λ‹ˆλ‹€. first λŠ” 거의 μ˜λ―Έκ°€ μ—†μŠ΅λ‹ˆλ‹€.

이 λ¬Έμ œλŠ” (적어도) 2012λ…„ μ΄ν›„λ‘œ μ•Œλ €μ Έ μžˆμŠ΅λ‹ˆλ‹€. nonzero(A)[0][0] κ°€ A 전체λ₯Ό κ²€μƒ‰ν•˜μ§€ λͺ»ν•˜λ„둝 ν•˜λŠ” 방법에 λŒ€ν•œ μ—…λ°μ΄νŠΈκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

λͺ¨λ“  μš”μ†Œλ₯Ό ​​항상 μŠ€μΊ”ν•˜λŠ” 이λ₯Έλ°” Pythonic λ°©μ‹μž…λ‹ˆκΉŒ?

@yunyoulu : ufunc λ°©μ‹μž…λ‹ˆλ‹€. ν•œ 걸음 λ’€λ‘œ λ¬ΌλŸ¬λ‚˜μ„œ numpyμ—μ„œ 닀단계 κ³„μ‚°μ˜ 일반적인 ν”„λ‘œμ„ΈμŠ€μ™€ ν•„μš”ν•œ 패슀 수λ₯Ό μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

  1. np.argwhere(x)[0] - 데이터 1회 톡과
  2. np.argwhere(f(x))[0] - λ°μ΄ν„°μ˜ 2회 전달을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  3. np.argwhere(f(g(x)))[0] - λ°μ΄ν„°μ˜ 3회 전달을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

ν•œ 가지 μ˜΅μ…˜μ€ np.first ν•¨μˆ˜ λ˜λŠ” 이와 μœ μ‚¬ν•œ κΈ°λŠ₯을 λ„μž…ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 그러면 λ‹€μŒκ³Ό 같이 ν‘œμ‹œλ©λ‹ˆλ‹€. μ—¬κΈ°μ„œ k <= 1 λŠ” 첫 번째 μš”μ†Œμ˜ μœ„μΉ˜μ— 따라 λ‹€λ¦…λ‹ˆλ‹€.

  1. np.first(x)[0] - λ°μ΄ν„°μ˜ 0+k 패슀λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  2. np.first(f(x))[0] - λ°μ΄ν„°μ˜ 1+k 패슀λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.
  3. np.first(f(g(x)))[0] - λ°μ΄ν„°μ˜ 2+k 패슀λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ λ¬Όμ–΄λ³Ό μ§ˆλ¬Έμ€ - 이 μ ˆμ•½μ΄ 정말 κ·Έλ§Œν•œ κ°€μΉ˜κ°€ μžˆμŠ΅λ‹ˆκΉŒ? NumpyλŠ” 근본적으둜 게으λ₯Έ μ»΄ν“¨νŒ… ν”Œλž«νΌμ΄ μ•„λ‹ˆλ©° κ³„μ‚°μ˜ λ§ˆμ§€λ§‰ 단계λ₯Ό 게으λ₯Έ κ²ƒμœΌλ‘œ λ§Œλ“œλŠ” 것은 μ΄μ „μ˜ λͺ¨λ“  단계가 그렇지 μ•Šμ€ 경우 특히 κ°€μΉ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€.


μ‹œλŒ€μ— 뒀쳐진

@eric-wieser

μ €λŠ” κ·Έ 말이 μ˜³μ§€ μ•Šλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. μ–΄λ–€ λ¬Έμ œμ— λŒ€ν•΄ k = 10 인 경우 np.first(f(x))[0] 에 λŒ€ν•œ 데이터 전달이 1+10=11 κ°€ μ•„λ‹™λ‹ˆλ‹€.

(간결함을 μœ„ν•΄ @eric-wieserκ°€ νŽΈμ§‘ν–ˆμŠ΅λ‹ˆλ‹€. 이 λŒ€ν™”λŠ” 이미 λ„ˆλ¬΄ κΉλ‹ˆλ‹€)

이 κΈ°λŠ₯의 ν•„μš”μ„±μ„ κ°€μž₯ 많이 λŠλΌλŠ” μ‚¬μš© μ‚¬λ‘€λŠ” A κ°€ A.shape = (n_1, n_2, ..., n_m) $ κ°€ μžˆλŠ” 큰 ν…μ„œμΌ λ•Œμž…λ‹ˆλ‹€. μ΄λŸ¬ν•œ 경우 np.first(A) λŠ” n_1*n_2*...*n_m A k μš”μ†Œλ§Œ 확인해야 ν•©λ‹ˆλ‹€(잠재적으둜 μƒλ‹Ήν•œ 절감 효과).

이 κΈ°λŠ₯의 ν•„μš”μ„±μ€ Aκ°€ 큰 ν…μ„œμΌ λ•Œ κ°€μž₯ 많이 λ΄…λ‹ˆλ‹€.

μ•„λ§ˆλ„ 이 κ²½μš°μ— 당신은 이미 λ°μ΄ν„°μ˜ 전체 패슀λ₯Ό ν•œ 번 이상 μ™„λ£Œν–ˆμœΌλ―€λ‘œ 기껏해야 두 λ°° λΉ λ₯΄κ²Œ μ‹€ν–‰λ˜λŠ” μ½”λ“œλ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

μ—¬κΈ°μ„œ λ¬Όμ–΄λ³Ό μ§ˆλ¬Έμ€ - 이 μ ˆμ•½μ΄ 정말 κ·Έλ§Œν•œ κ°€μΉ˜κ°€ μžˆμŠ΅λ‹ˆκΉŒ? NumpyλŠ” 근본적으둜 게으λ₯Έ μ»΄ν“¨νŒ… ν”Œλž«νΌμ΄ μ•„λ‹ˆλ©° κ³„μ‚°μ˜ λ§ˆμ§€λ§‰ 단계λ₯Ό 게으λ₯Έ κ²ƒμœΌλ‘œ λ§Œλ“œλŠ” 것은 μ΄μ „μ˜ λͺ¨λ“  단계가 그렇지 μ•Šμ€ 경우 특히 κ°€μΉ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€.

μ΄λŠ” ν™•λ¦½λœ 경우 "λ‹€λ₯Έ 것도 계산 쀑이고 μ—¬μ „νžˆ 느리기 λ•Œλ¬Έμ—" 계산 μ„±λŠ₯을 κ°œμ„ ν•˜κΈ° μœ„ν•œ 거의 λͺ¨λ“  λ…Έλ ₯을 λ‚­λΉ„ν•˜λŠ” 것을 μ •λ‹Ήν™”ν•˜λŠ” 데 μ‚¬μš©λ  수 μžˆλ‹€λŠ” ν₯미둜운 κ΄€μ μž…λ‹ˆλ‹€. (κΈ°ν›„λ³€ν™” 행동을 λΆ€μ •ν•˜λŠ” μ‚¬λžŒλ“€μ΄ μ‚¬μš©ν•˜λŠ” 것과 같은 μ£Όμž₯μž…λ‹ˆλ‹€. λ‹€λ₯Έ λ‚˜λΌκ°€ 무언가λ₯Ό ν•  λ•ŒκΉŒμ§€ μš°λ¦¬λ‚˜λΌμ—μ„œ 무언가λ₯Ό ν•˜λŠ” 것은 λˆ„κ΅¬μ—κ²Œλ„ 도움이 λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.) λ‚˜λŠ” μ „ν˜€ ν™•μ‹ ν•˜μ§€ λͺ»ν•©λ‹ˆλ‹€. kκ°€ 맀우 μž‘μ€ 잠재적으둜 맀우 μž‘μ€ 1/k만큼 κ³„μ‚°μ˜ 일뢀 속도λ₯Ό 높일 수 μžˆλŠ” κΈ°νšŒκ°€ μžˆλ‹€λ©΄, 제 μƒκ°μ—λŠ” 그럴 κ°€μΉ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ λŒ€ν™”μ‹μœΌλ‘œ μž‘μ—…ν•  λ•Œ(Jupyter λ“±) 맀우 자주 λ³„λ„μ˜ μ…€μ—μ„œ 데이터 "전달"을 μˆ˜ν–‰ν•˜λ―€λ‘œ κ²°κ΅­ 전체 μ…€μ˜ 속도도 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

np.first(f(x))[0] - λ°μ΄ν„°μ˜ 1+k 패슀λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.

@eric-wieser μ‹€μ œλ‘œ 2017년에 이 문제λ₯Ό λ³΄μ•˜μ„ λ•Œ np.firstwhere(x, array_or_value_to_compare) μΌμ’…μ˜ np.firstwhere(x, array_or_value_to_compare) λ₯Ό ν–₯ν•œ 첫 번째 단계가 되기λ₯Ό μ •λ§λ‘œ λ°”λžμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ‹€μ œλ‘œ νŠΉμ • μ‚¬λ‘€μ΄μ§€λ§Œ 제 κ²½ν—˜μƒ μ€‘μš”ν•©λ‹ˆλ‹€. f(x) .

@toobaz : κ·Έ μ˜ˆμ—μ„œ f = lambda x: x == value_to_compare κ°€ μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.

이것이 λ°”λ‘œ λ‚΄κ°€ 이 길을 κ°€λŠ” 것을 μ‘°μ‹¬ν•˜λŠ” μ΄μœ μž…λ‹ˆλ‹€(cc @bersbersbers). μ£Όμ˜ν•˜μ§€ μ•ŠμœΌλ©΄ λ‹€μŒκ³Ό 같이 λλ‚©λ‹ˆλ‹€.

  1. np.first(x) - 패슀 λŒ€ 0이 μ•„λ‹Œ κ°’ μ €μž₯
  2. np.first_equal(x, v) - 패슀 μ €μž₯ vs first(np.equal(x, v))
  3. np.first_square_equal(x*x, v) - 패슀 μ €μž₯ vs first_equal(np.square(x), v)

이것이 μ „ν˜€ ν™•μž₯λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것은 맀우 λΆ„λͺ…ν•΄μ•Ό ν•˜λ©° μ–΄λ”˜κ°€μ— 선을 κ·Έλ €μ•Ό ν•©λ‹ˆλ‹€. λ‚˜λŠ” 1이 ν—ˆμš©λ˜λŠ” 것에 μ•½κ°„ μ°¬μ„±ν•˜μ§€λ§Œ 2κ°€ ν—ˆμš©λ˜λŠ” 것은 이미 API ν‘œλ©΄μ μ˜ 폭발적이며 3은 λ‚˜μ—κ²Œ 맀우 ν˜„λͺ…ν•˜μ§€ λͺ»ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€.

np.first 에 μ°¬μ„±ν•˜λŠ” ν•œ 가지 μ£Όμž₯ - 이λ₯Ό κ΅¬ν˜„ν•˜λ©΄ np.first(x*x == v) _numa μ»¨ν…μŠ€νŠΈ λ‚΄μ—μ„œ_ μ‹€μ œλ‘œλŠ” 단일 패슀λ₯Ό _μˆ˜ν–‰_ν•˜λ„λ‘ numba λ₯Ό 특수 μΌ€μ΄μŠ€λ‘œ 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ–΄μ¨Œλ“  문제의 ν˜„μž¬ μƒνƒœλ₯Ό λͺ…ν™•νžˆ ν•˜λŠ” numpyμ—μ„œ 게으λ₯Έ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 것을 μ•„λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μ„±λŠ₯ 쑰정이 ν™•μž₯μ„±μ—μ„œλ§Œ κ³ λ €λ˜λŠ” κ²½μš°μ—λŠ” νŽΈμ•ˆν•¨μ„ λŠλΌμ§€ λͺ»ν•©λ‹ˆλ‹€.

κ°„λ‹¨ν•œ μ§ˆλ¬Έμ„ ν•΄λ³΄μž. μ˜€λŠ˜λ‚  개인용 컴퓨터가 ν™•μž₯되고 μžˆμŠ΅λ‹ˆκΉŒ? λŒ€λ‹΅μ€ ν™•μ‹€νžˆ NO μž…λ‹ˆλ‹€. 3λ…„ μ „ ν‘œμ€€ λ…ΈνŠΈλΆμ„ κ΅¬μž…ν•˜λ©΄ 8GB λ©”λͺ¨λ¦¬κ°€ μž₯μ°©λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 이제 μ‹œμž₯μ—μ„œ μ—¬μ „νžˆ 8GBλ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λͺ¨λ“  μ†Œν”„νŠΈμ›¨μ–΄λŠ” 이전보닀 2λ°° λ˜λŠ” 4λ°° 더 λ§Žμ€ λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 적어도 μ›Œν¬μŠ€ν…Œμ΄μ…˜μ€ ν΄λŸ¬μŠ€ν„°μ™€ 같은 λ°©μ‹μœΌλ‘œ ν™•μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ³΅μž‘μ„±μ„ μ „ν˜€ λ³€κ²½ν•˜μ§€ μ•Šκ³  ν•¨μˆ˜λ₯Ό 10λ°° 느리게 λ§Œλ“œλŠ” 것은 ν•œ 데이터 κ³Όν•™μžλ₯Ό 미치게 λ§Œλ“€κΈ°μ— μΆ©λΆ„ν•©λ‹ˆλ‹€. μ„€λ Ή ν”„λ‘œνŒŒμΌλ§μ„ 톡해 병λͺ© ν˜„μƒμ„ νŒŒμ•…ν•˜λ”λΌλ„ κ·Έκ°€ ν•  수 μžˆλŠ” μš°μ•„ν•œ 일은 μ—†μŠ΅λ‹ˆλ‹€.

λ‚΄κ°€ μžμ„Ένžˆ μ„€λͺ…ν•˜λ €κ³  ν•˜λŠ” 것은 게으λ₯Έ 처리λ₯Ό μˆ˜ν–‰ν•  수 μžˆλŠ” λŠ₯λ ₯을 κ°–λŠ” 것이 항상 λ°”λžŒμ§ν•˜λ©° μ‹œμŠ€ν…œμ˜ 응닡성과 μ–Έμ–΄λ₯Ό μ‚¬μš©ν•˜λŠ” μ‚¬λžŒλ“€μ˜ 생산성에 μ€‘μš”ν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 라이브러리 개발의 μ–΄λ €μ›€μ΄λ‚˜ μž‘μ—…λŸ‰μ€ μ΄λŸ¬ν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜μ§€ μ•ŠλŠ” 것에 λŒ€ν•œ μ•„μ£Ό 쒋은 λ³€λͺ…이며 ν™•μ‹€νžˆ 이해할 수 μžˆμ§€λ§Œ μœ μš©ν•˜μ§€ μ•Šλ‹€κ³  λ§ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€.

@toobaz : κ·Έ μ˜ˆμ—μ„œ f = lambda x: x == value_to_compare κ°€ μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.

μ˜³μ€

이것이 λ°”λ‘œ λ‚΄κ°€ 이 길을 κ°€λŠ” 것을 μ‘°μ‹¬ν•˜λŠ” μ΄μœ μž…λ‹ˆλ‹€(cc @bersbersbers). μ£Όμ˜ν•˜μ§€ μ•ŠμœΌλ©΄ λ‹€μŒκ³Ό 같이 λλ‚©λ‹ˆλ‹€.

1. `np.first(x)` - save a pass vs nonzero

2. `np.first_equal(x, v)` - save a pass vs `first(np.equal(x, v))`

3. `np.first_square_equal(x*x, v)` - save a pass vs `first_equal(np.square(x), v)`

λ‚˜λŠ” λ‹Ήμ‹ μ˜ 우렀λ₯Ό μ΄ν•΄ν•˜μ§€λ§Œ $#$3 np.square_where #$ 에 λŒ€ν•΄ 묻지 μ•Šμ„ 것(아무도 묻지 μ•ŠκΈ°λ₯Ό λ°”λžλ‹ˆλ‹€)처럼 μ •ν™•νžˆ np.first_square_equal λ₯Ό μš”κ΅¬ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. 그리고 예, 3을 μˆ˜ν–‰ν•˜λ©΄ λ°μ΄ν„°μ˜ 전체 전달을 μ˜λ―Έν•œλ‹€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ v λŠ” ν•œ 번 μƒμ„±λ˜λ©° x 의 μ—¬λŸ¬ λ‹€λ₯Έ 값을 μ°Ύμ•„μ•Ό ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. . 예λ₯Ό λ“€μ–΄(간단함을 μœ„ν•΄ 예제 2둜 λŒμ•„κ°‘λ‹ˆλ‹€.) 30개의 κ°€λŠ₯ν•œ λ²”μ£Όκ°€ λͺ¨λ‘ 10^9 ν•­λͺ© 배열에 λ‚˜νƒ€λ‚˜λŠ”μ§€ ν™•μΈν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 그리고 λ‚˜λŠ” 그것듀이 λͺ¨λ‘ 처음 10^3 μš”μ†Œ 사이에 λ‚˜νƒ€λ‚  것이라고 κ°•λ ₯히 μ˜μ‹¬ν•©λ‹ˆλ‹€.

λ¨Όμ € 이전 μ˜κ²¬μ„ λͺ…ν™•νžˆ ν•˜κ² μŠ΅λ‹ˆλ‹€. 직관에 λ§žλŠ” ν•¨μˆ˜λ‘œ np.firstwhere(x, array_or_value_to_compare) λ₯Ό μ‚¬μš©ν•˜κ³  μ‹Άμ§€λ§Œ 2017년에 μžˆμ—ˆλ˜ 계산 λ¬Έμ œλŠ” np.first μžˆμ–΄λ„ ν•΄κ²°λ˜μ—ˆμ„ κ²ƒμž…λ‹ˆλ‹€.

λ‘˜μ§Έ, μš”μ μ€ - 제 μƒκ°μ—λŠ” - 단일 호좜의 μ‹€ν–‰ μ‹œκ°„λ§Œμ΄ μ•„λ‹™λ‹ˆλ‹€. μ–΄μ¨Œλ“  2.와 3을 ν•˜λ €λ©΄ 데이터λ₯Ό μ™„μ „νžˆ νŒ¨μŠ€ν•΄μ•Ό ν•˜λŠ” 것이 μ‚¬μ‹€μ΄μ§€λ§Œ... 데이터λ₯Ό μ΄ˆκΈ°ν™”ν•  λ•Œ 이미 이 패슀λ₯Ό μˆ˜ν–‰ν–ˆμ„ μˆ˜λ„ 있고 μ§€κΈˆμ€ 속도λ₯Ό 높일 방법을 μ°Ύκ³  μžˆμŠ΅λ‹ˆλ‹€. λΉˆλ²ˆν•œ μž‘μ—….

np.first 이 ν‘œμ€€ numpy μ ‘κ·Ό λ°©μ‹μ—μ„œ μ‹€μ œλ‘œ λ²—μ–΄λ‚˜λŠ” λ‹Ήμ‹ μ˜ μš”μ μ„ λ³΄μ•˜κ³ , 잘 κ΅¬ν˜„ν•˜λŠ” 것이 μ€‘μš”ν•˜μ§€ μ•Šμ„ 수 μžˆλ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€... λ‚΄κ°€ 보지 λͺ»ν•˜λŠ” 것은 그것이 λ‚˜λ¨Έμ§€ APIλ₯Ό "감염"μ‹œν‚€λŠ” λ°©λ²•μž…λ‹ˆλ‹€. λ˜λŠ” 자체적으둜 λŒ€κ·œλͺ¨ APIλ₯Ό ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

즉, μ‹€μ œλ‘œ numpy λ²”μœ„λ₯Ό 벗어났닀고 μƒκ°ν•œλ‹€λ©΄ λŒ€μ‹  μž‘μ€ 독립 νŒ¨ν‚€μ§€μ˜ λ²”μœ„κ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš” 폴,

κ·€ν•˜μ˜ μ†”λ£¨μ…˜μ„ np.flatnonzero 및 py_find_1st ν™•μž₯κ³Ό λΉ„κ΅ν•˜λŠ” μž‘μ€ 벀치마크λ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

λ²€μΉ˜λ§ˆν¬κ°€ μ²¨λΆ€λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

μ—¬κΈ° κ²°κ³Ό

(κΈ°λ³Έ) m3088.roebel: (ν…ŒμŠ€νŠΈ) (g:master)514> ./benchmark.py
utf1st.find_1st(rr, μ œν•œ, utf1st.cmp_equal)::
λŸ°νƒ€μž„ 0.131초
np.flatnonzero(rr==ν•œκ³„)[0]::
λŸ°νƒ€μž„ 2.121초
next((ii의 경우 ii, vv == limit)인 경우 enumerate(rr)의 vv)::
λŸ°νƒ€μž„ 1.612초

λ”°λΌμ„œ μ œμ•ˆλœ μ†”λ£¨μ…˜μ€ ν•„μš”ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— flatnonzero보닀 25% λΉ λ¦…λ‹ˆλ‹€.
κ²°κ³Ό 배열을 생성할 λ•Œ μ—¬μ „νžˆ py_find_1st.find_1st보닀 ~12 λŠλ¦½λ‹ˆλ‹€.

μ΅œμƒμ˜
μ•…μ…€

νŽΈμ§‘ν•˜λ‹€:
λ©”μΌλ‘œ λ‹΅μž₯을 보낸 λ©”μ‹œμ§€κ°€ 사라지고 λ‚΄ 메일에 λ²€μΉ˜λ§ˆν¬λ„ μ²¨λΆ€λœ 것 κ°™μŠ΅λ‹ˆλ‹€. λ²€μΉ˜λ§ˆν¬λŠ” μ—¬κΈ°

https://github.com/roebel/py_find_1st/blob/master/test/benchmark.py

μ†ŒμŒ μ£„μ†‘ν•©λ‹ˆλ‹€.

2020-05-15 17:33에 PKλŠ” λ‹€μŒκ³Ό 같이 μΌμŠ΅λ‹ˆλ‹€.

|next(i for i, v in enumerate(x) if v)|λŠ” μ–΄λ–»μŠ΅λ‹ˆκΉŒ?

β€”
당신이 μ–ΈκΈ‰λ˜μ—ˆκΈ° λ•Œλ¬Έμ— 이것을 λ°›λŠ” κ²ƒμž…λ‹ˆλ‹€.
이 이메일에 직접 λ‹΅μž₯ν•˜κ±°λ‚˜ GitHub https://github.com/numpy/numpy/issues/2269#issuecomment-629314457 μ—μ„œ ν™•μΈν•˜κ±°λ‚˜ ꡬ독을 μ·¨μ†Œν•˜μ„Έμš”.
https://github.com/notifications/unsubscribe-auth/ACAL2LS2YZALARHBHNABVILRRVOEPANCNFSM4ABV5HGA .

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰

κ΄€λ ¨ 문제

inducer picture inducer  Β·  3μ½”λ©˜νŠΈ

toddrjen picture toddrjen  Β·  4μ½”λ©˜νŠΈ

Levstyle picture Levstyle  Β·  3μ½”λ©˜νŠΈ

perezpaya picture perezpaya  Β·  4μ½”λ©˜νŠΈ

kevinzhai80 picture kevinzhai80  Β·  4μ½”λ©˜νŠΈ