Frage

Gibt es eine vorhandene Funktion in numpy, die mir sagen, ob ein Wert ist entweder ein numerischer Typ oder ein numpy Array? Ich bin einige Datenverarbeitungs Code zu schreiben, die Zahlen in verschiedenen Darstellungen verarbeiten muss (durch „Nummer“ ich jede Darstellung einer numerischen Menge bedeuten, die mit dem Standard arithmetischen Operatoren manipuliert werden können, +, -, *, /, * *).

Einige Beispiele für das Verhalten Ich suche

>>> is_numeric(5)
True
>>> is_numeric(123.345)
True
>>> is_numeric('123.345')
False
>>> is_numeric(decimal.Decimal('123.345'))
True
>>> is_numeric(True)
False
>>> is_numeric([1, 2, 3])
False
>>> is_numeric([1, '2', 3])
False
>>> a = numpy.array([1, 2.3, 4.5, 6.7, 8.9])
>>> is_numeric(a)
True
>>> is_numeric(a[0])
True
>>> is_numeric(a[1])
True
>>> is_numeric(numpy.array([numpy.array([1]), numpy.array([2])])
True
>>> is_numeric(numpy.array(['1'])
False

Wenn keine solche Funktion vorhanden ist, ich weiß es nicht schwer sein sollte, einen zu schreiben, so etwas wie

isinstance(n, (int, float, decimal.Decimal, numpy.number, numpy.ndarray))

aber gibt es andere numerische Typen I in der Liste enthalten soll?

War es hilfreich?

Lösung

Wie andere beantwortet haben, könnte es sein, andere numerische Typen außer denen, die Sie erwähnen. Ein Ansatz wäre ausdrücklich zu prüfen, für die Funktionen, die Sie wollen, mit so etwas wie

# Python 2
def is_numeric(obj):
    attrs = ['__add__', '__sub__', '__mul__', '__div__', '__pow__']
    return all(hasattr(obj, attr) for attr in attrs)

# Python 3
def is_numeric(obj):
    attrs = ['__add__', '__sub__', '__mul__', '__truediv__', '__pow__']
    return all(hasattr(obj, attr) for attr in attrs)

Dies funktioniert für alle Beispiele mit Ausnahme des letzten, numpy.array(['1']). Das ist, weil numpy.ndarray die speziellen Methoden für numerische Operationen hat aber wirft Typeerror, wenn Sie versuchen, sie mit einer Schnur oder Objekt-Arrays unangemessen zu verwenden. Sie könnten eine explizite Kontrolle für diese wie

hinzufügen
 ... and not (isinstance(obj, ndarray) and obj.dtype.kind in 'OSU')

Das kann gut genug sein.

Aber ... man kann nie sein 100% sicher, dass jemand nicht eine andere Art mit dem gleichen Verhalten definieren, so eine absolut sichere Methode tatsächlich versuchen, eine Berechnung zu tun und fangen die Ausnahme, so etwas wie

def is_numeric_paranoid(obj):
    try:
        obj+obj, obj-obj, obj*obj, obj**obj, obj/obj
    except ZeroDivisionError:
        return True
    except Exception:
        return False
    else:
        return True

, aber je nachdem, wie oft planen Sie nennt es verwenden und mit welchen Argumenten, dies kann nicht sinnvoll sein (es kann möglicherweise langsam sein, zum Beispiel mit großen Arrays).

Andere Tipps

Im Allgemeinen ist die flexible, schnelle und pythonic Weise unbekannte Typen zu handhaben ist, sich nur auf sie eine Operation durchführen und eine Ausnahme auf ungültige Arten zu fangen.

try:
    a = 5+'5'
except TypeError:
    print "Oops"

Es scheint mir, dass dieser Ansatz ist einfacher, als Spezial-Gehäuse eine Funktion, um absolute Sicherheit Typen zu bestimmen.

Auch numpy hat numpy.isreal und andere ähnliche Funktionen (numpy.is + Tab sollte sie aufführen).

Sie haben alle ihren Spaß Eckfällen aber einer von denen könnte nützlich sein.

Ihre is_numeric ist schlecht definiert. Sehen Sie meine Kommentare auf Ihre Frage.

Andere numerische Typen können sein: long, complex, fractions.Fraction, numpy.bool_, numpy.ubyte, ...

operator.isNumberType() kehrt True für Python Zahlen und numpy.array.

Seit Python 2.6 Sie isinstance(d, numbers.Number) anstelle veralteten operator.isNumberType() verwenden können.

Im Allgemeinen ist es besser, die Fähigkeiten des Objekts (zum Beispiel, ob Sie eine ganze Zahl hinzufügen kann) und nicht seine Art.

isinstance(numpy.int32(4), numbers.Number) kehrt False, so dass durchaus nicht funktioniert. operator.isNumberType() funktioniert auf allen Varianten von numpy Zahlen jedoch einschließlich numpy.array([1]).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top