Pythonでnumpyタイプを識別する方法は?


99

オブジェクトがnumpy型であるかどうかを確実に判断するにはどうすればよいですか?

この質問はダックタイピングの哲学に反することを理解していますが、アイデアは、(scipyとnumpyを使用する)関数がnumpyタイプで呼び出されない限り、numpyタイプを返さないことを確認することです。 これは別の質問の解決策に現れますが、オブジェクトが派手なタイプであるかどうかを判断する一般的な問題は、元の質問から十分離れているため、それらを分離する必要があります。


1つの質問:あなた(またはscipy)がnumpy型をサブクラス化する型を定義する場合、それは重要かどうか?(Pythonでnumpy型をサブクラス化することはできないと思いますが、Cモジュールでも可能です。また、PyPyでnumpypy型をサブクラス化することもできると思うので、おそらく問題ではありませんが、可能であるとは考えられません。)
abarnert 2012

私はそのことを考えていませんでした。基本的にあなたのコメントは質問が予想よりも難しいことを指摘しています。正直なところ、そのような高レベルの検討は、私の状況にとっては行き過ぎです。一般的で移植性のある答えについては、動作が定義されている限り問題ありません。
ダグラスB.ステープル2012

回答:


114

組み込み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は十分な数の型ではありませんか?
panda-34

numpy。*に何かが必要な場合は、モジュールの親パッケージを歩くだけです。(その時点で、明らかに関数でラップする必要があります。)そして、pandas DataFramesをnumpyishとしてカウントする場合は、またはを追加して、それをテストします。等々。要点は、緩やかな手動タイプ切り替えのような珍しいことをしたいときに、実際に何を求めているのかを知る必要があるということですが、一度知ってしまえば、実装は簡単です。
abarnert 2016年

1
この解決策は、隠された属性に依存しているため、非常に不自然なようです。しかし、それは単に好みの問題なのでしょうか?
j08lue

2
@ j08lueこれらは非表示の属性ではなく、特別な属性が文書化されています。それにもかかわらず、それは非Pythonicですが、それは問題に固有のことだと思います。(そして、あなたが言語が落胆する何かをしたいとき、最良の解決策は通常、あなたが通常悪い考えである何かをしていることを指摘するのに目に見えて醜いというのがPythonの強みだと思います。)
abarnert

68

私が思いついた解決策は次のとおりです:

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

ただし、すべてのnumpyタイプがまたはのいずれかであることが保証されていることは100%明確ではありません。これはおそらくバージョンの堅牢性ではありません。np.ndarraynp.generic


1
dir(numpy)型と組み込み関数(およびクラスですが、それはないと思います)をフィルターに掛け、それを使用して、isinstance対するタプルを生成できます。(組み込み関数を実際に型コンストラクターであるかどうかにかかわらず、インスタンスに渡すことができると思いますが、それを確認する必要があります。)
abarnert

はい、それらはすべてこれら2つのAFAIKのサブクラスである必要があります。
seberg 2012

@sebergありがとう。確かに今のところそうですが、Pythonのドキュメントはこれについてあまり明確ではなく、将来的には変更される可能性があります。
ダグラスB.ステープル2012

19

古い質問ですが、例を挙げて明確な答えを出しました。これと同じ問題があり、明確な答えが見つからなかったので、質問を新鮮に保つことに害はありません。重要なのは、numpyインポートしたことを確認してから、isinstanceブール値を実行することです。これは簡単に思えるかもしれませんが、さまざまなデータ型に対していくつかの計算を行っている場合、この小さなチェックは、いくつかの厄介なベクトル化演算を開始する前の簡単なテストとして役立ちます。

##################
# 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をリロードしないようにしてください。ただし、それ以外の場合は問題ありません。MaskedArraysmatrixrecarrayのすべてのサブクラスですndarrayので、あなたが設定する必要があります。
  • スカラーが厄介なスカラーであるかどうかをテストする場合、状況は少し複雑になります。shapedtype属性があるかどうかを確認できます。dtypeこれを基本的なdtype と比較できますnp.core.numerictypes.genericTypeRank。そのリストはで確認できます。このリストの要素は文字列であるため、tested.dtype is np.dtype(an_element_of_the_list)... を実行する必要があることに注意してください。

+1。「numpyタイプである」以外のものを実際に探していて、それが何かを定義できる場合、これは他の答えよりも優れています。そして、ほとんどの場合、あなたが定義できる何か特定のものを探しているべきです。
abarnert 2012

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 2012

モジュールを使用することは、確かに優れたソリューションです。
Roland Smith


@ Omkaar.K正規表現は何に使用できますか?まったく同じチェックをもう少し複雑な方法で行うには?
abarnert 2018

@abamert "Could"は私が言ったことです。また、正規表現はこれらのような単純なタスクでは複雑に見える可能性がありますが、大きな文字列処理タスクには非常に役立つので、それを学ぶことは悪い考えではありません。あなたのポートフォリオがあなたを上級プログラマーとして描いているので、あなたはすでに知っていると思いますか?
Omkaar.K 2018

3

type(numpy.ndarray)typeそれ自体であり、ブール型とスカラー型に注意してください。それが直感的でも簡単でもない場合でも、落胆しないでください。最初は苦痛です。

参照: - https://docs.scipy.org/doc/numpy-1.15.1/reference/arrays.dtypes.html - https://github.com/machinalis/mypy-data/tree/master/numpy-ミピー

>>> 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.