파이썬에서 numpy 유형을 식별하는 방법은 무엇입니까?


100

객체에 numpy 유형이 있는지 어떻게 안정적으로 결정할 수 있습니까?

이 질문이 덕 타이핑의 철학에 위배된다는 것을 알고 있지만, 아이디어는 scipy와 numpy를 사용하는 함수가 numpy 유형으로 호출되지 않는 한 numpy 유형을 반환하지 않도록하는 것입니다. 이것은 다른 질문에 대한 해결책으로 나오지만, 객체가 numpy 유형을 가지고 있는지를 결정하는 일반적인 문제는 분리되어야하는 원래의 질문에서 충분히 멀리 떨어져 있다고 생각합니다.


한 가지 질문 : numpy 유형을 하위 클래스로 분류하는 유형을 정의하는 경우 (또는 예를 들어 scipy) 그 값이 계산되어야합니까? (파이썬에서 numpy 유형을 하위 클래스화할 수 없다고 생각하지만 C 모듈에서는 가능하며, PyPy에서 numpypy 유형을 하위 클래스화할 수도 있다고 생각합니다…
abarnert

나는 그것을 생각하지 않았다. 기본적으로 귀하의 의견은 질문이 예상보다 어렵다고 지적합니다. 솔직히 그런 종류의 높은 수준의 고려는 내 상황에 너무 과잉입니다. 일반적이고 이식 가능한 대답의 경우 동작이 정의되는 한 괜찮습니다.
Douglas B. Staple

답변:


116

내장 type함수를 사용하여 유형을 가져온 다음 __module__속성을 사용하여 정의 된 위치를 찾을 수 있습니다 .

>>> import numpy as np
a = np.array([1, 2, 3])
>>> type(a)
<type 'numpy.ndarray'>
>>> type(a).__module__
'numpy'
>>> type(a).__module__ == np.__name__
True

예를 들어 numpy.ma.MaskedArray가 numpy 충분한 유형이 아닙니까?
panda-34

numpy. *에서 원하는 것이 있다면 모듈의 부모 패키지를 따라 가면됩니다. (그 시점에서 분명히 함수로 래핑하고 싶을 것입니다.) 그리고 pandas DataFrames가 numpyish로 계산되도록하려면 또는를 추가하여 테스트합니다. 등등. 요점은 느슨한 수동 유형 전환과 같은 특이한 작업을 수행하고 싶을 때 실제로 요구하는 것이 무엇인지 알아야하지만 일단 알게되면 구현하기 쉽습니다.
abarnert

1
이 솔루션은 숨겨진 속성에 의존하는 매우 비 파이썬처럼 보입니다. 하지만 그게 맛의 문제일까요?
j08lue

2
@ j08lue 숨겨진 속성이 아니라 문서화 된 특수 속성입니다. 그럼에도 불구하고 비정상적이지만 문제에 내재되어 있다고 생각합니다. (그리고 언어가 권장하지 않는 일을하고 싶을 때 가장 좋은 해결책은 일반적으로 나쁜 생각 인 일을하고 있다고
말할

69

내가 생각 해낸 해결책은 다음과 같습니다.

isinstance(y, (np.ndarray, np.generic) )

그러나 모든 numpy 유형이 또는 중 하나임을 보장하는 것은 100 % 명확 하지 않으며 이는 버전이 견고하지 않을 수 있습니다.np.ndarraynp.generic


1
dir(numpy)유형과 내장 함수 (및 클래스가 있다고 생각하지 않음)를 필터링 하고이를 사용하여 튜플을 생성 할 수 있다고 가정합니다 isinstance. (실제로 형식 생성자인지 아닌지 여부에 관계없이 내장 함수를 isinstance에 전달할 수 있다고 생각하지만 확인해야합니다.)
abarnert

예, 모두이 두 AFAIK의 하위 클래스 여야합니다.
seberg

@seberg 감사합니다. 확실히 지금은 그런 것 같지만 파이썬 문서 는 이것에 대해 명확하지 않으며 미래에 변경 될 수 있습니다.
Douglas B. Staple

19

오래된 질문이지만 예를 들어 확실한 대답을 얻었습니다. 동일한 문제가 있었고 명확한 답을 찾지 못했기 때문에 질문을 최신 상태로 유지하는 것이 아프지 않습니다. 핵심은 numpy가져 왔는지 확인한 다음 isinstancebool 을 실행하는 것 입니다. 간단 해 보일 수 있지만 다른 데이터 유형에 대해 계산을 수행하는 경우이 작은 검사는 벡터화 된 작업을 시작하기 전에 빠른 테스트 역할을 할 수 있습니다.

##################
# important part!
##################

import numpy as np

####################
# toy array for demo
####################

arr = np.asarray(range(1,100,2))

########################
# The instance check
######################## 

isinstance(arr,np.ndarray)

9

그것은 실제로 당신이 찾고있는 것에 달려 있습니다.

  • 시퀀스가 실제로 있는지 테스트하려면 ndarraya isinstance(..., np.ndarray)가 가장 쉬울 것입니다. 모듈이 다를 수 있으므로 백그라운드에서 numpy를 다시로드하지 않도록하십시오. 그렇지 않으면 괜찮습니다. MaskedArrays, matrix, recarray의 모든 서브 클래스 ndarray그래서 당신은 설정해야합니다.
  • 스칼라가 numpy 스칼라인지 테스트하려면 상황이 좀 더 복잡해집니다. shapedtype속성 이 있는지 확인할 수 있습니다 . dtype에서 찾을 수있는 목록의 기본 dtypes와 비교할 수 있습니다 np.core.numerictypes.genericTypeRank. 이 목록의 요소는 문자열이므로 다음을 수행해야합니다 tested.dtype is np.dtype(an_element_of_the_list).

+1. 실제로 " numpy유형입니다 "가 아닌 다른 것을 찾고 있고 그것이 무엇인지 정의 할 수 있다면 이것은 다른 답변보다 낫습니다. 그리고 대부분의 경우에, 당신은 해야 사용자가 정의 할 수있는 뭔가 특정 찾고있을.
abarnert

8

유형을 얻으려면 내장 type함수를 사용하십시오 . in연산자를 사용하면 문자열이 포함되어 있는지 확인하여 유형이 numpy 유형인지 테스트 할 수 있습니다 numpy.

In [1]: import numpy as np

In [2]: a = np.array([1, 2, 3])

In [3]: type(a)
Out[3]: <type 'numpy.ndarray'>

In [4]: 'numpy' in str(type(a))
Out[4]: True

(이 예제는 IPython 에서 실행되었습니다 . 대화 형 사용과 빠른 테스트에 매우 편리합니다.)


2
이것은 작동하지만 "numpygroup"이라고하는 유형을 정의하면 오 탐지가 발생합니다. 또한 유형의 문자열 표현에 따라 피할 수 있다면 나쁜 생각입니다.이 경우에는 할 수 있습니다. 대신 모듈을보십시오.
abarnert

모듈을 사용하는 것이 실제로 더 나은 솔루션입니다.
Roland Smith

정규식을 사용할 수 있습니다
omkaartg

@ Omkaar.K Regex는 무엇을 위해 사용될 수 있습니까? 약간 더 복잡한 방식으로 똑같은 검사를 수행하려면?
abarnert

@abamert "Could"는 내가 말한 것입니다. 또한 정규식은 이와 같은 간단한 작업에서는 복잡해 보일 수 있지만 큰 문자열 처리 작업에는 매우 유용하므로 배우는 것이 나쁘지 않습니다. 당신의 포트폴리오가 당신을 선임 프로그래머로 묘사 한 이후로 이미 알고있는 것 같아요?
omkaartg

3

참고가 type(numpy.ndarray)A는 type자체 부울 스칼라 유형에 대한 조심을. 직관적이거나 쉽지 않은 경우 너무 낙심하지 마십시오. 처음에는 고통 스럽습니다.

참조 : -https : //docs.scipy.org/doc/numpy-1.15.1/reference/arrays.dtypes.html-https : //github.com/machinalis/mypy-data/tree/master/numpy- mypy

>>> import numpy as np
>>> np.ndarray
<class 'numpy.ndarray'>
>>> type(np.ndarray)
<class 'type'>
>>> a = np.linspace(1,25)
>>> type(a)
<class 'numpy.ndarray'>
>>> type(a) == type(np.ndarray)
False
>>> type(a) == np.ndarray
True
>>> isinstance(a, np.ndarray)
True

부울로 재미 :

>>> b = a.astype('int32') == 11
>>> b[0]
False
>>> isinstance(b[0], bool)
False
>>> isinstance(b[0], np.bool)
False
>>> isinstance(b[0], np.bool_)
True
>>> isinstance(b[0], np.bool8)
True
>>> b[0].dtype == np.bool
True
>>> b[0].dtype == bool  # python equivalent
True

스칼라 유형에 대한 더 많은 재미는 다음을 참조하십시오.- https //docs.scipy.org/doc/numpy-1.15.1/reference/arrays.scalars.html#arrays-scalars-built-in

>>> x = np.array([1,], dtype=np.uint64)
>>> x[0].dtype
dtype('uint64')
>>> isinstance(x[0], np.uint64)
True
>>> isinstance(x[0], np.integer)
True  # generic integer
>>> isinstance(x[0], int)
False  # but not a python int in this case

# Try matching the `kind` strings, e.g.
>>> np.dtype('bool').kind                                                                                           
'b'
>>> np.dtype('int64').kind                                                                                          
'i'
>>> np.dtype('float').kind                                                                                          
'f'
>>> np.dtype('half').kind                                                                                           
'f'

# But be weary of matching dtypes
>>> np.integer
<class 'numpy.integer'>
>>> np.dtype(np.integer)
dtype('int64')
>>> x[0].dtype == np.dtype(np.integer)
False

# Down these paths there be dragons:

# the .dtype attribute returns a kind of dtype, not a specific dtype
>>> isinstance(x[0].dtype, np.dtype)
True
>>> isinstance(x[0].dtype, np.uint64)
False  
>>> isinstance(x[0].dtype, np.dtype(np.uint64))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: isinstance() arg 2 must be a type or tuple of types
# yea, don't go there
>>> isinstance(x[0].dtype, np.int_)
False  # again, confusing the .dtype with a specific dtype


# Inequalities can be tricky, although they might
# work sometimes, try to avoid these idioms:

>>> x[0].dtype <= np.dtype(np.uint64)
True
>>> x[0].dtype <= np.dtype(np.float)
True
>>> x[0].dtype <= np.dtype(np.half)
False  # just when things were going well
>>> x[0].dtype <= np.dtype(np.float16)
False  # oh boy
>>> x[0].dtype == np.int
False  # ya, no luck here either
>>> x[0].dtype == np.int_
False  # or here
>>> x[0].dtype == np.uint64
True  # have to end on a good note!
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.