Saya memiliki fungsi yang mengambil argumen NBins
. Saya ingin melakukan panggilan ke fungsi ini dengan skalar 50
atau array [0, 10, 20, 30]
. Bagaimana saya bisa mengidentifikasi dalam fungsi, berapa panjangnyaNBins
? atau berkata berbeda, apakah itu skalar atau vektor?
Saya mencoba ini:
>>> N=[2,3,5]
>>> P = 5
>>> len(N)
3
>>> len(P)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
>>>
Seperti yang Anda lihat, saya tidak dapat menerapkan len
untuk P
, karena itu bukan array .... Apakah ada sesuatu seperti isarray
atauisscalar
di python?
Terima kasih
type
?Jawaban:
Untuk mendukung semua jenis urutan, periksa
collections.Sequence
bukanlist
.Catatan :
isinstance
juga mendukung tuple kelas, periksatype(x) in (..., ...)
harus dihindari dan tidak perlu.Anda mungkin juga ingin memeriksanya
not isinstance(x, (str, unicode))
sumber
list
kesalahan pada skalar ... terima kasihcollections.Sequence
adalah ABC untuk string juga, sehingga harus diperhitungkan. Saya menggunakan sesuatu sepertiif type(x) is not str and isinstance(x, collections.Sequence):
. Ini tidak bagus, tetapi dapat diandalkan.type
, dan juga periksanot isinstance(x, (str, unicode))
Python 2Jawaban sebelumnya mengasumsikan bahwa array adalah daftar standar python. Sebagai seseorang yang sering menggunakan numpy, saya akan merekomendasikan tes yang sangat pythonic:
sumber
__len__
atribut (jadi saya kira, secara teknis bukan tipe skalar)if hasattr(N, '__len__') and (not isinstance(N, str))
akan menjelaskan string dengan benar.Menggabungkan jawaban @jamylak dan @ jpaddison3 bersamaan, jika Anda harus kuat terhadap array numpy sebagai input dan menanganinya dengan cara yang sama seperti daftar, Anda harus menggunakan
Ini kuat terhadap subclass daftar, array tuple dan numpy.
Dan jika Anda ingin menjadi kuat terhadap semua subclass urutan lainnya juga (bukan hanya daftar dan tuple), gunakan
Mengapa Anda melakukan hal-hal seperti ini dengan
isinstance
dan tidak membandingkantype(P)
dengan nilai target? Berikut adalah contoh, di mana kita membuat dan mempelajari perilakuNewList
, subkelas daftar sepele.Meskipun
x
dany
membandingkan sebagai sama, menangani merekatype
akan menghasilkan perilaku yang berbeda. Namun, karenax
adalah sebuah contoh dari subclass darilist
, menggunakanisinstance(x,list)
memberi perilaku yang diinginkan dan memperlakukanx
dany
dengan cara yang sama.sumber
isinstance(P, (list, tuple, set, np.ndarray))
Apakah ada yang setara dengan isscalar () di numpy? Iya.
sumber
>>> np.isscalar('abcd')
pengembalianTrue
.return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
numpy.isscalar()
Fungsi menderita sejumlah cacat desain dapat didamaikan dan akan mungkin akan usang di beberapa revisi mendatang. Mengutip dokumentasi resmi : "Dalam hampir semua kasusnp.ndim(x) == 0
harus digunakan, bukannp.isscaler(x)
, karena yang pertama juga akan benar dengan benar untuk array 0d." Alternatif yang kompatibel dengan maju yang kuatnumpy.isscalar()
adalah dengan membungkus secara sepelenumpy.ndim()
: misalnya,def is_scalar(obj): return np.ndim(obj) == 0
np.isscalar
membingungkan. Doc resmi disarankan menggunakan dinp.array.ndim
mana - mana, yaitunp.isscalar(np.array(12))
Salah sementara itu harus dianggap sebagai skalar karenanp.array(12).ndim
0.Sementara, pendekatan @ jamylak adalah yang lebih baik, berikut adalah pendekatan alternatif
sumber
type(p) in (list, )
.Pendekatan alternatif lain (penggunaan properti nama kelas ):
Tidak perlu mengimpor apa pun.
sumber
Berikut adalah pendekatan terbaik yang saya temukan: Periksa keberadaan
__len__
dan__getitem__
.Anda mungkin bertanya mengapa? Alasannya meliputi:
isinstance(obj, abc.Sequence)
gagal pada beberapa objek termasuk PyTorch's Tensor karena mereka tidak mengimplementasikan__contains__
.__len__
dan__getitem__
yang saya rasa adalah metode minimal untuk objek seperti array.Jadi tanpa basa-basi lagi:
Perhatikan bahwa saya telah menambahkan parameter default karena sebagian besar waktu Anda mungkin ingin mempertimbangkan string sebagai nilai, bukan array. Demikian pula untuk tupel.
sumber
sumber
Anda dapat memeriksa tipe data variabel.
Ini akan memberi Anda put sebagai tipe data P.
Sehingga Anda dapat membedakan bahwa itu adalah bilangan bulat atau array.
sumber
Saya terkejut bahwa pertanyaan mendasar seperti itu tampaknya tidak memiliki jawaban langsung dengan python. Tampak bagi saya bahwa hampir semua jawaban yang diajukan menggunakan semacam pengecekan jenis, yang biasanya tidak disarankan dalam python dan mereka tampaknya terbatas pada kasus tertentu (mereka gagal dengan tipe numerik yang berbeda atau objek iterat generik yang tidak tupel atau daftar).
Bagi saya, yang berfungsi lebih baik adalah mengimpor numpy dan menggunakan array.size, misalnya:
Perhatikan juga:
tapi:
sumber
Cukup gunakan
size
sajalen
!sumber
np.size(5)
dannp.size([5])
keduanya ==1
, jadi ini tidak benar membedakan tipe (yaitu, mengidentifikasi skalar), yang saya percaya adalah tujuannya.preds_test [0] memiliki bentuk (128.128,1). Mari kita periksa tipe datanya menggunakan isinstance () function isinstance mengambil 2 argumen. Argumen 1 adalah data Argumen ke-2 adalah tipe data isinstance (preds_test [0], np.ndarray) memberikan Output sebagai True. Itu berarti preds_test [0] adalah sebuah array.
sumber
Untuk menjawab pertanyaan dalam judul, cara langsung untuk mengetahui apakah suatu variabel adalah skalar adalah dengan mencoba mengubahnya menjadi float. Jika Anda mendapatkannya
TypeError
, itu tidak benar.sumber