Ich habe eine Funktion, die das Argument übernimmt NBins
. Ich möchte diese Funktion mit einem Skalar 50
oder einem Array aufrufen [0, 10, 20, 30]
. Wie kann ich innerhalb der Funktion identifizieren, wie lang sie NBins
ist? oder anders gesagt, wenn es ein Skalar oder ein Vektor ist?
Ich habe es versucht:
>>> 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()
>>>
Wie Sie sehen, kann ich nicht anwenden len
zu P
, da es kein Array ist .... Gibt es so etwas wie isarray
oder isscalar
in Python?
Vielen Dank
type
?Antworten:
Um jede Art von Sequenz zu unterstützen, aktivieren Sie
collections.Sequence
anstelle vonlist
.Hinweis :
isinstance
Unterstützt auch ein Tupel von Klassen, Überprüfungtype(x) in (..., ...)
sollte vermieden werden und ist nicht erforderlich .Sie können auch überprüfen
not isinstance(x, (str, unicode))
quelle
list
, um für Skalare falsch zu werden ... dankecollections.Sequence
aber auch ein ABC für Zeichenfolge, so dass dies berücksichtigt werden sollte. Ich benutze so etwas wieif type(x) is not str and isinstance(x, collections.Sequence):
. Das ist nicht großartig, aber zuverlässig.type
, und überprüfen Sie auchnot isinstance(x, (str, unicode))
auf Python 2Bei früheren Antworten wird davon ausgegangen, dass das Array eine Python-Standardliste ist. Als jemand, der häufig Numpy verwendet, würde ich einen sehr pythonischen Test empfehlen von:
quelle
__len__
Attribut (also denke ich, technisch gesehen keinif hasattr(N, '__len__') and (not isinstance(N, str))
würde richtig für Strings erklären.Wenn Sie die Antworten von @jamylak und @ jpaddison3 miteinander kombinieren, sollten Sie verwenden, wenn Sie gegenüber numpy-Arrays als Eingabe robust sein und diese wie Listen behandeln möchten
Dies ist robust gegenüber Unterklassen von Listen-, Tupel- und Numpy-Arrays.
Und wenn Sie auch gegenüber allen anderen Sequenzunterklassen (nicht nur Liste und Tupel) robust sein möchten, verwenden Sie
Warum sollten Sie die Dinge so machen
isinstance
und nichttype(P)
mit einem Zielwert vergleichen ? Hier ist ein Beispiel, in dem wir das VerhaltenNewList
einer trivialen Unterklasse von Listen erstellen und untersuchen .Trotz
x
undy
Vergleich als gleichtype
würde der Umgang mit ihnen zu unterschiedlichem Verhalten führen. Da jedochx
eine Instanz einer Unterklasselist
, mitisinstance(x,list)
dem gewünschten Verhalten und behandelt ergibtx
undy
auf die gleiche Weise.quelle
isinstance(P, (list, tuple, set, np.ndarray))
Gibt es ein Äquivalent zu isscalar () in numpy? Ja.
quelle
>>> np.isscalar('abcd')
kehrt zurückTrue
.return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
numpy.isscalar()
Funktion weist eine Reihe unüberbrückbarer Konstruktionsfehler auf und wird wahrscheinlich bei einer zukünftigen Überarbeitung veraltet sein. Um die offizielle Dokumentation zu paraphrasieren : "In fast allen Fällennp.ndim(x) == 0
sollte stattdessen verwendet werdennp.isscaler(x)
, da erstere auch für 0d-Arrays korrekt true zurückgeben." Eine robuste vorwärtskompatible Alternative zunumpy.isscalar()
wäre daher, trivial zu verpackennumpy.ndim()
: zBdef is_scalar(obj): return np.ndim(obj) == 0
np.isscalar
es verwirrend ist. Offizielles Dokument schlug vor,np.array.ndim
überall zu verwenden, dhnp.isscalar(np.array(12))
ist falsch, während es als skalar betrachtet werden sollte, danp.array(12).ndim
es 0 ist.Während @ jamylaks Ansatz der bessere ist, gibt es hier einen alternativen Ansatz
quelle
type(p) in (list, )
.Ein weiterer alternativer Ansatz (Verwendung von Klassenname - Eigenschaft):
Sie müssen nichts importieren.
quelle
Hier ist der beste Ansatz, den ich gefunden habe: Überprüfen Sie die Existenz von
__len__
und__getitem__
.Sie fragen sich vielleicht warum? Die Gründe umfassen:
isinstance(obj, abc.Sequence)
schlägt bei einigen Objekten fehl, einschließlich PyTorchs Tensor, da sie nicht implementiert werden__contains__
.__len__
und__getitem__
was meiner Meinung nach minimale Methoden für Array-ähnliche Objekte sind.Also ohne weiteres:
Beachten Sie, dass ich Standardparameter hinzugefügt habe, da Sie Zeichenfolgen meistens als Werte und nicht als Arrays betrachten möchten. Ähnliches gilt für Tupel.
quelle
quelle
Sie können den Datentyp der Variablen überprüfen.
Es wird Ihnen als Datentyp von P ausgegeben.
Damit Sie unterscheiden können, dass es sich um eine Ganzzahl oder ein Array handelt.
quelle
Ich bin überrascht, dass eine so grundlegende Frage in Python keine unmittelbare Antwort zu haben scheint. Es scheint mir, dass fast alle vorgeschlagenen Antworten eine Art Typprüfung verwenden, die in Python normalerweise nicht empfohlen wird, und sie scheinen auf einen bestimmten Fall beschränkt zu sein (sie schlagen mit verschiedenen numerischen Typen oder generischen iterierbaren Objekten fehl, die keine Tupel oder Listen sind).
Für mich funktioniert es besser, numpy zu importieren und array.size zu verwenden, zum Beispiel:
Beachten Sie auch:
aber:
quelle
Einfach verwenden
size
stattlen
!quelle
np.size(5)
undnp.size([5])
sind beide ==1
, so dass dies den Typ nicht richtig unterscheidet (dh einen Skalar identifiziert), was meiner Meinung nach das Ziel ist.preds_test [0] hat die Form (128,128,1). Überprüfen Sie den Datentyp mithilfe der Funktion isinstance (). isinstance akzeptiert 2 Argumente. 1. Argument ist Daten 2. Argument ist Datentyp isinstance (preds_test [0], np.ndarray) gibt Output als True aus. Dies bedeutet, dass preds_test [0] ein Array ist.
quelle
Um die Frage im Titel zu beantworten, können Sie direkt feststellen, ob eine Variable ein Skalar ist, indem Sie versuchen, sie in einen Float zu konvertieren. Wenn Sie bekommen
TypeError
, ist es nicht.quelle