Programing

Python의 MATLAB 스타일 find () 함수

lottogame 2020. 12. 29. 06:42
반응형

Python의 MATLAB 스타일 find () 함수


MATLAB에서는 특정 조건을 충족하는 값의 인덱스를 쉽게 찾을 수 있습니다.

>> a = [1,2,3,1,2,3,1,2,3];
>> find(a > 2)     % find the indecies where this condition is true
[3, 6, 9]          % (MATLAB uses 1-based indexing)
>> a(find(a > 2))  % get the values at those locations
[3, 3, 3]

파이썬에서 이것을 수행하는 가장 좋은 방법은 무엇입니까?

지금까지 다음을 생각해 냈습니다. 값을 얻으려면 :

>>> a = [1,2,3,1,2,3,1,2,3]
>>> [val for val in a if val > 2]
[3, 3, 3]

그러나 각 값의 색인을 원하면 조금 더 복잡합니다.

>>> a = [1,2,3,1,2,3,1,2,3]
>>> inds = [i for (i, val) in enumerate(a) if val > 2]
>>> inds
[2, 5, 8]
>>> [val for (i, val) in enumerate(a) if i in inds]
[3, 3, 3]

특히 임의의 조건 ( 'val> 2'뿐만 아니라)에 대해 Python에서이를 수행하는 더 좋은 방법이 있습니까?

NumPy에서 MATLAB 'find'에 해당하는 함수를 찾았지만 현재 해당 라이브러리에 액세스 할 수 없습니다.


목록 이해의 조건 부분에서 사용될 호출 가능한 매개 변수를 취하는 함수를 만들 수 있습니다. 그런 다음 람다 또는 기타 함수 객체를 사용하여 임의의 조건을 전달할 수 있습니다.

def indices(a, func):
    return [i for (i, val) in enumerate(a) if func(val)]

a = [1, 2, 3, 1, 2, 3, 1, 2, 3]

inds = indices(a, lambda x: x > 2)

>>> inds
[2, 5, 8]

numpy를 모두로드하지 않고도 Matlab 예제에 조금 더 가깝습니다.


numpy에서 당신은 where:

>> import numpy as np
>> x = np.random.randint(0, 20, 10)
>> x
array([14, 13,  1, 15,  8,  0, 17, 11, 19, 13])
>> np.where(x > 10)
(array([0, 1, 3, 6, 7, 8, 9], dtype=int64),)

또는 numpy의 0이 아닌 함수를 사용하십시오.

import numpy as np
a    = np.array([1,2,3,4,5])
inds = np.nonzero(a>2)
a[inds] 
array([3, 4, 5])

이것을 사용하지 않는 이유 :

[i for i in range(len(a)) if a[i] > 2]

또는 임의의 조건에 대해 조건에 ​​대한 함수 f정의하고 다음 을 수행하십시오.

[i for i in range(len(a)) if f(a[i])]

numpy더 일반적으로이 응용 프로그램에 사용되는 루틴이다 numpy.where(); 그래도 numpy.nonzero().

import numpy
a    = numpy.array([1,2,3,4,5])
inds = numpy.where(a>2)

값을 얻으려면 인덱스를 저장하고 함께 슬라이스 할 수 있습니다.

a[inds]

또는 배열을 선택적 매개 변수로 전달할 수 있습니다.

numpy.where(a>2, a)

또는 여러 어레이 :

b = numpy.array([11,22,33,44,55])
numpy.where(a>2, a, b)

임의의 조건이있는 값을 얻으려면 filter()람다 함수와 함께 사용할 수 있습니다 .

>>> a = [1,2,3,1,2,3,1,2,3]
>>> filter(lambda x: x > 2, a)
[3, 3, 3]

인덱스를 얻는 한 가지 가능한 방법 enumerate()은 인덱스와 값이 모두있는 튜플을 빌드하는 데 사용 하고이를 필터링하는 것입니다.

>>> a = [1,2,3,1,2,3,1,2,3]
>>> aind = tuple(enumerate(a))
>>> print aind
((0, 1), (1, 2), (2, 3), (3, 1), (4, 2), (5, 3), (6, 1), (7, 2), (8, 3))
>>> filter(lambda x: x[1] > 2, aind)
((2, 3), (5, 3), (8, 3))

I've been trying to figure out a fast way to do this exact thing, and here is what I stumbled upon (uses numpy for its fast vector comparison):

a_bool = numpy.array(a) > 2
inds = [i for (i, val) in enumerate(a_bool) if val]

It turns out that this is much faster than:

inds = [i for (i, val) in enumerate(a) if val > 2]

It seems that Python is faster at comparison when done in a numpy array, and/or faster at doing list comprehensions when just checking truth rather than comparison.

Edit:

I was revisiting my code and I came across a possibly less memory intensive, bit faster, and super-concise way of doing this in one line:

inds = np.arange( len(a) )[ a < 2 ]

I think I may have found one quick and simple substitute. BTW I felt that the np.where() function not very satisfactory, in a sense that somehow it contains an annoying row of zero-element.

import matplotlib.mlab as mlab
a = np.random.randn(1,5)
print a

>> [[ 1.36406736  1.45217257 -0.06896245  0.98429727 -0.59281957]]

idx = mlab.find(a<0)
print idx
type(idx)

>> [2 4]
>> np.ndarray

Best, Da


Matlab's find code has two arguments. John's code accounts for the first argument but not the second. For instance, if you want to know where in the index the condition is satisfied: Mtlab's function would be:

find(x>2,1)

Using John's code, all you have to do is add a [x] at the end of the indices function, where x is the index number you're looking for.

def indices(a, func):
    return [i for (i, val) in enumerate(a) if func(val)]

a = [1, 2, 3, 1, 2, 3, 1, 2, 3]

inds = indices(a, lambda x: x > 2)[0] #[0] being the 2nd matlab argument

which returns >>> 2, the first index to exceed 2.

ReferenceURL : https://stackoverflow.com/questions/5957470/matlab-style-find-function-in-python

반응형