die vorherigen Antworten zu vervollständigen, ist hier eine Numexpr Implementierung (mit einem möglichen Rückfall auf Numpy),
import numpy as np
from numpy import arctan2, sqrt
import numexpr as ne
def cart2sph(x,y,z, ceval=ne.evaluate):
""" x, y, z : ndarray coordinates
ceval: backend to use:
- eval : pure Numpy
- numexpr.evaluate: Numexpr """
azimuth = ceval('arctan2(y,x)')
xy2 = ceval('x**2 + y**2')
elevation = ceval('arctan2(z, sqrt(xy2))')
r = eval('sqrt(xy2 + z**2)')
return azimuth, elevation, r
Für große Feldgrößen, ermöglicht dies einen Faktor von 2 Geschwindigkeit im Vergleich zur reinen einer Numpy Implementierung , und wäre vergleichbar mit C oder Cython-Geschwindigkeiten. Die vorliegende numpy Lösung (wenn sie mit dem ceval=eval
Argument verwendet) ist ebenfalls um 25% schneller als die appendSpherical_np
Funktion in der @mtrw Antwort für große Array Größen
In [1]: xyz = np.random.rand(3000000,3)
...: x,y,z = xyz.T
In [2]: %timeit -n 1 appendSpherical_np(xyz)
1 loops, best of 3: 397 ms per loop
In [3]: %timeit -n 1 cart2sph(x,y,z, ceval=eval)
1 loops, best of 3: 280 ms per loop
In [4]: %timeit -n 1 cart2sph(x,y,z, ceval=ne.evaluate)
1 loops, best of 3: 145 ms per loop
obwohl für kleinere Größen appendSpherical_np
ist eigentlich schneller,
In [5]: xyz = np.random.rand(3000,3)
...: x,y,z = xyz.T
In [6]: %timeit -n 1 appendSpherical_np(xyz)
1 loops, best of 3: 206 µs per loop
In [7]: %timeit -n 1 cart2sph(x,y,z, ceval=eval)
1 loops, best of 3: 261 µs per loop
In [8]: %timeit -n 1 cart2sph(x,y,z, ceval=ne.evaluate)
1 loops, best of 3: 271 µs per loop
Gute Arbeit, meine Cython-Lösung ist nur ein bisschen schneller (1,23 Sekunden vs. 1,54 Sekunden auf meinem Rechner). Aus irgendeinem Grund habe ich die vektorisierte arctan2-Funktion nicht gesehen, als ich gerade mit numpy geradeaus gesucht habe. +1 –
Anon vorgeschlagen 'ptsnew [:, 4] = np.arctan2 (np.sqrt (xy), xyz [:, 2])' –
siehe: http://stackoverflow.com/edit-suggestions/756 –