Es scheint wie np.apply_along_axis
versucht herauszufinden, was die resultierende Form sein sollte, basierend auf dem Ergebnis des Aufrufs func
. Wenn Ihr Eingabe-Array die Form (n, m)
hat und Ihr func
einen Wert mit der Länge k
zurückgibt, gibt np.apply_along_axis(func, -1, a)
ein Array mit der Form (n, k)
zurück. Dies gilt auch dann, wenn Ihre Funktion etwas anderes als eine Liste oder ein Array zurückgibt. Wenn Ihre Funktion einen Skalar zurückgibt, lautet die resultierende Form (n,)
.
Beispiele:
# np.diff(a[0]) has length 9.
>>> np.apply_along_axis(lambda x: np.diff(x), -1, a).shape
(2, 9)
# sorted(a[0]) has length 10
>>> np.apply_along_axis(lambda x: sorted(x), -1, a).shape
(2, 10)
# len(a[0]) is a scalar
>>> np.apply_along_axis(lambda x: len(x), -1, a).shape
(2,)
nun in Ihrem Fall, da Sie eine dict
mit einer Länge von 2, die sich ergebende Form ist (2, 2)
sind zurück. Eine einfache Problemumgehung wäre, das Wörterbuch in etwas zu verpacken, das ein Skalar ist. Aber anscheinend mag numpy benutzerdefinierte Skalare nicht. Also, wenn Sie versuchen, eine benutzerdefinierte DictWrap
Klasse wie folgt zu verwenden:
class DictWrap(object):
def __init__(self, *args, **kwargs):
self._d = dict(*args, **kwargs)
... es funktioniert nicht:
>>> np.apply_along_axis(lambda x: DictWrap(k1=1, k2=len(x)), -1, a)
...
TypeError: object of type 'DictWrap' has no len()
Also entweder wir müssen eine benutzerdefinierte __len__()
Methode DictWrap
hinzufügen, die zurückgibt 1, oder wir können das Wörterbuch in einer Liste wickeln:
>>> np.apply_along_axis(lambda x: [dict(k1=1, k2=len(x))], -1, a)
array([[{'k2': 10, 'k1': 1}],
[{'k2': 10, 'k1': 1}]], dtype=object)
Dies hat eine Form (2, 1)
. Sie können squeeze()
auf nennen es ein 1-d-Array zu erhalten:
>>> r = np.apply_along_axis(lambda x: [dict(k1=1, k2=len(x))], -1, a)
>>> r.squeeze()
array([{'k2': 10, 'k1': 1}, {'k2': 10, 'k1': 1}], dtype=object)
Eine andere, und vielleicht die einfachste, würde Weg sein, die zusätzlichen Dimensionen loszuwerden selbst:
>>> r = np.apply_along_axis(lambda x: dict(k1=1, k2=len(x)), -1, a)
>>> r[:, 0]
array([{'k2': 10, 'k1': 1}, {'k2': 10, 'k1': 1}], dtype=object)
zu sehen, wie genau nummerische Griffe in verschiedenen Fällen, siehe documentation of apply_along_axis
(besonders ab if isscalar(res):
).
Ich muss sagen, "numpy" macht selbstgefällige Dinge – Lee