Python'da numpy türleri nasıl belirlenir?


101

Bir nesnenin uyuşmuş bir türü olup olmadığı nasıl güvenilir bir şekilde belirlenebilir?

Bu sorunun ördek yazma felsefesine aykırı olduğunun farkındayım, ancak fikir, (scipy ve numpy kullanan) bir işlevin, uyuşuk bir türle çağrılmadıkça asla bir uyuşuk türü döndürmediğinden emin olmaktır. Bu, başka bir sorunun çözümünde ortaya çıkıyor, ancak bence bir nesnenin uyuşuk bir tipe sahip olup olmadığını belirleme genel sorunu, ayrılmaları gereken orijinal sorudan yeterince uzak.


Bir soru: Eğer (ya da, scipy diyelim), uyuşmuş bir türü alt sınıflara ayıran bir türü tanımlıyorsanız, bu geçerli mi olmalı mı? (Python'da numpy türleri alt sınıflayamayacağınıza inanıyorum, ancak bir C modülünde yapabilirsiniz ve bence PyPy'de numpypy türlerini de alt sınıflara ayırabilirsiniz ... bu yüzden muhtemelen önemli değil, ama yapabileceği düşünülemez değil.)
abarnert

Bunu düşünmemiştim; temelde yorumunuz sorunun beklenenden daha zor olduğuna işaret ediyor. Dürüst olmak gerekirse, bu tür bir üst düzey değerlendirme benim durumum için fazlasıyla abartılı. Genel ve taşınabilir cevap için, davranış tanımlandığı sürece sorun olmadığını söyleyebilirim.
Douglas B. Staple

Yanıtlar:


117

typeTürü almak için yerleşik işlevini kullanın , ardından __module__özelliği nerede tanımlandığını bulmak için kullanabilirsiniz :

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

örneğin numpy.ma.MaskedArray yeterince uyuşmuş bir tip değil mi?
panda-34

Eğer numpy. * İçinde herhangi bir şey istiyorsanız, sadece modülün ana paketini yürütün. (Bu noktada, tabii ki onu bir işlevin içine yerleştirmek istersiniz.) Ve pandaların DataFrames'ın uyuşmuş olarak sayılmasını istiyorsanız, bunu test etmek için veya ekleyin. Ve bunun gibi. Mesele şu ki, gevşek manuel tip değiştirme gibi alışılmadık bir şey yapmak istediğinizde aslında ne istediğinizi bilmelisiniz, ancak bir kez öğrendikten sonra, uygulanması kolaydır.
abarnert

1
Bu çözüm, gizli niteliklere bağlı olarak çok tutarsız görünüyor. Ama belki bu sadece bir zevk meselesidir?
j08lue

2
@ j08lue Gizli nitelikler değiller, özel nitelikleri belgelenmiş. Yine de pitonik değil, ama bence bu sorunun doğasında var. (Ve dilin cesaretini kırdığı bir şeyi yapmak istediğinizde, en iyi çözümün normalde kötü bir fikir olan bir şeyi yaptığınızı
söylemeye

73

Bulduğum çözüm şu:

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

Bununla birlikte, tüm uyuşmuş türlerin ya ya da olması garantili olduğu % 100 net değildir ve bu muhtemelen sürüm sağlam değildir.np.ndarraynp.generic


1
Sanırım dir(numpy)türler ve yerleşik işlevler (ve sınıflar, ancak hiç olduğunu sanmıyorum) filtreleyebilir ve bunu, isinstancegüçlü bir tuple oluşturmak için kullanabilirsiniz . (Yerleşik işlevleri, aslında tip kurucu olup olmadıklarına bakılmaksızın anlık duruma geçirebileceğinize inanıyorum, ancak bunu kontrol etmeniz gerekir.)
abarnert

Evet, hepsi bu iki AFAIK'in alt sınıfları olmalıdır.
seberg

@seberg Teşekkürler. Şimdilik kesinlikle böyle görünüyor, ancak python dokümantasyonu bu konuda çok net değil ve gelecekte makul bir şekilde değişebilir.
Douglas B. Staple

20

Eski soru ama bir örnekle kesin bir cevap buldum. Aynı sorunu yaşadığım ve net bir cevap bulamadığım için soruları güncel tutmaktan zarar gelmez. Anahtar, numpyiçe isinstanceaktardığınızdan emin olmak ve ardından bool'u çalıştırmaktır . Bu basit görünse de, farklı veri türlerinde bazı hesaplamalar yapıyorsanız, bu küçük kontrol, bazı sompy vektörleştirilmiş işlemlere başlamadan önce hızlı bir test görevi görebilir.

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

Bu aslında ne aradığına bağlı.

  • Bir dizinin gerçekten a olup olmadığını test etmek istiyorsanız ndarray, a isinstance(..., np.ndarray)muhtemelen en kolayıdır. Modül farklı olabileceğinden numpy'yi arka planda yeniden yüklemediğinizden emin olun, aksi takdirde iyi olmalısınız. MaskedArrays, matrix, recarrayTüm alt sınıfları ndarrayböylece ayarlanması gerekir.
  • Bir skalerin uyuşmuş bir skaler olup olmadığını test etmek istiyorsanız, işler biraz daha karmaşık hale gelir. Bir shapeve bir dtypeniteliği olup olmadığını kontrol edebilirsiniz . dtypeListesini bulabileceğiniz temel dtype'lerle karşılaştırabilirsiniz np.core.numerictypes.genericTypeRank. Bu listenin öğelerinin dizeler olduğunu unutmayın, bu nedenle bir tested.dtype is np.dtype(an_element_of_the_list)...

+1. Aslında " numpytiptir" dışında bir şey arıyorsanız ve bu şeyin ne olduğunu tanımlayabiliyorsanız, bu diğer cevaplardan daha iyidir. Ve çoğu durumda, sen gerektiğini izlemeyi ayarlarken bir şey özgü arıyor.
abarnert

8

Türü elde etmek için yerleşik typeişlevi kullanın . İle intip o dize içerip içermediğini kontrol ederek bir numpy türüyse operatörü test edebilirsiniz 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

(Bu örnek, bu arada IPython'da çalıştırıldı . Etkileşimli kullanım ve hızlı testler için çok kullanışlı.)


2
Bu işe yarar, ancak "numpygroup" olarak adlandırılan bir tür tanımlarsanız, yanlış pozitifler alırsınız. Ayrıca, türlerin dizgi temsiline bağlı olarak, bundan kaçınabiliyorsanız kötü bir fikirdir ve bu durumda yapabilirsiniz. Bunun yerine modülüne bakın.
abarnert

Modülü kullanmak gerçekten daha iyi bir çözümdür.
Roland Smith


@ Omkaar.K Regex ne için kullanılabilir? Aynı kontrolü biraz daha karmaşık bir şekilde yapmak için?
abarnert

@abamert "Olabilir" dedim, regex de bu gibi basit görevler için karmaşık görünebilir, ancak büyük dizgi işleme görevleri için son derece yararlıdır, Bu yüzden öğrenmek kötü bir fikir değil. Sanırım portföyünüz sizi kıdemli bir programcı olarak gösterdiğinden beri bunu zaten biliyorsunuzdur?
omkaartg

3

Not olduğu type(numpy.ndarray)bir olduğunu typekendisi ve boole ve sayıl tipler dikkat edin. Sezgisel veya kolay değilse cesaretiniz kırılmasın, ilk başta bir acıdır.

Ayrıca bkz .: - 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

Booleanlarla eğlence:

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

Skaler türlerle daha eğlenceli, bkz: - 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!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.