NumPy 배열에 숫자가 아닌 값이 하나 이상 포함되어 있는지 탐지하시겠습니까?
입력에 숫자가 아닌 하나 이상의 값이 포함되어 있는지 감지하는 함수를 작성해야 합니다.숫자가 아닌 값이 발견되면 오류가 발생합니다(계산은 숫자 값만 반환해야 하므로).입력 배열의 치수 수는 미리 알 수 없습니다. 함수는 ndim과 관계없이 정확한 값을 제공해야 합니다.추가적인 복잡성으로 입력은 단일 플로트 또는numpy.float64
아니면 심지어 0차원 배열 같은 이상한 것도.
이 문제를 해결하는 분명한 방법은 배열에서 반복 가능한 모든 개체에 대해 비-이터라베를 찾을 때까지 반복하는 재귀 함수를 작성하는 것입니다.다음을 적용합니다.numpy.isnan()
모든 반복할 수 없는 개체에 대한 함수입니다.숫자가 아닌 값이 하나 이상 발견되면 함수는 즉시 False를 반환합니다.그렇지 않으면 반복 가능한 모든 값이 숫자인 경우 True가 반환됩니다.
그것은 잘 작동하지만, 꽤 느리고, 나는 NumPy가 훨씬 더 나은 방법을 가지고 있다고 기대합니다.더 빠르고 더 무기력한 대안은 무엇입니까?
다음은 제 모형입니다.
def contains_nan( myarray ):
"""
@param myarray : An n-dimensional array or a single float
@type myarray : numpy.ndarray, numpy.array, float
@returns: bool
Returns true if myarray is numeric or only contains numeric values.
Returns false if at least one non-numeric value exists
Not-A-Number is given by the numpy.isnan() function.
"""
return True
이 작업은 반복하는 것보다 빨라야 하며 모양에 관계없이 작동합니다.
numpy.isnan(myarray).any()
편집: 30배 더 빠름:
import timeit
s = 'import numpy;a = numpy.arange(10000.).reshape((100,100));a[10,10]=numpy.nan'
ms = [
'numpy.isnan(a).any()',
'any(numpy.isnan(x) for x in a.flatten())']
for m in ms:
print " %.2f s" % timeit.Timer(m, s).timeit(1000), m
결과:
0.11 s numpy.isnan(a).any()
3.75 s any(numpy.isnan(x) for x in a.flatten())
보너스: 어레이가 아닌 NumPy 유형에 적합합니다.
>>> a = numpy.float64(42.)
>>> numpy.isnan(a).any()
False
>>> a = numpy.float64(numpy.nan)
>>> numpy.isnan(a).any()
True
무한대가 가능한 값이라면 numpy.isfinite를 사용할 것입니다.
numpy.isfinite(myarray).all()
위 사항이 다음과 같이 평가되는 경우True
,그리고나서myarray
포함되지 않음numpy.nan
,numpy.inf
또는-numpy.inf
.
numpy.isnan
괜찮으실 겁니다numpy.inf
값, 예:
In [11]: import numpy as np
In [12]: b = np.array([[4, np.inf],[np.nan, -np.inf]])
In [13]: np.isnan(b)
Out[13]:
array([[False, False],
[ True, False]], dtype=bool)
In [14]: np.isfinite(b)
Out[14]:
array([[ True, False],
[False, False]], dtype=bool)
잠깐만! 마이크로초!나노초 안에 해결할 수 있는 문제를 마이크로초 안에 절대 풀지 마세요.
허용된 답변:
- 난이 발견되었는지 여부에 관계없이 전체 데이터에 대해 반복합니다.
- 크기가 N인 임시 배열을 생성합니다. 이 배열은 중복됩니다.
더 나은 해결책은 NAN이 발견되면 True를 즉시 반환하는 것입니다.
import numba
import numpy as np
NAN = float("nan")
@numba.njit(nogil=True)
def _any_nans(a):
for x in a:
if np.isnan(x): return True
return False
@numba.jit
def any_nans(a):
if not a.dtype.kind=='f': return False
return _any_nans(a.flat)
array1M = np.random.rand(1000000)
assert any_nans(array1M)==False
%timeit any_nans(array1M) # 573us
array1M[0] = NAN
assert any_nans(array1M)==True
%timeit any_nans(array1M) # 774ns (!nanoseconds)
n차원에서 작동합니다.
array1M_nd = array1M.reshape((len(array1M)/2, 2))
assert any_nans(array1M_nd)==True
%timeit any_nans(array1M_nd) # 774ns
이를 numpy 네이티브 솔루션과 비교해 보십시오.
def any_nans(a):
if not a.dtype.kind=='f': return False
return np.isnan(a).any()
array1M = np.random.rand(1000000)
assert any_nans(array1M)==False
%timeit any_nans(array1M) # 456us
array1M[0] = NAN
assert any_nans(array1M)==True
%timeit any_nans(array1M) # 470us
%timeit np.isnan(array1M).any() # 532us
조기 종료 방법은 3개 주문 또는 매그니튜드 속도 향상(경우에 따라)입니다.간단한 주석을 달기에는 너무 초라하지 않습니다.
(np.where(np.isnan(A)))[0].shape[0]
보다 클 것입니다.0
한다면A
의 요소를 하나 이상 포함합니다.nan
,A
그럴 수도 있습니다n x m
매트릭스.
예:
import numpy as np
A = np.array([1,2,4,np.nan])
if (np.where(np.isnan(A)))[0].shape[0]:
print "A contains nan"
else:
print "A does not contain nan"
numpy 1.3 또는 svn을 사용하여 이를 수행할 수 있습니다.
In [1]: a = arange(10000.).reshape(100,100)
In [3]: isnan(a.max())
Out[3]: False
In [4]: a[50,50] = nan
In [5]: isnan(a.max())
Out[5]: True
In [6]: timeit isnan(a.max())
10000 loops, best of 3: 66.3 µs per loop
비교에서 난스의 처리는 이전 버전에서 일관되지 않았습니다.
언급URL : https://stackoverflow.com/questions/911871/detect-if-a-numpy-array-contains-at-least-one-non-numeric-value
'sourcecode' 카테고리의 다른 글
UIPickerView가 로드된 후 행 선택 (0) | 2023.07.27 |
---|---|
정적 필드는 내부적으로 정확히 어떻게 작동합니까? (0) | 2023.07.27 |
jQuery 또는 CSS 선택기를 사용하여 일부 문자열로 시작하는 모든 ID 선택 (0) | 2023.07.27 |
내 코드가 Windows로 컴파일되고 있는지 확인할 수 있는 매크로가 있습니까? (0) | 2023.07.27 |
노드 모듈 이름에 @ 기호 사용 (0) | 2023.07.27 |