Чтобы завершить предыдущие ответы, вот Numexpr реализация (с возможностью отката к 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
Для больших размеров массивов, это позволяет в 2 раза скорости до по сравнению с чистой реализации Numpy , и будет сопоставим с скоростями C или Cython. Присутствует NumPy раствор (при использовании с ceval=eval
аргумента) также на 25% быстрее, чем appendSpherical_np
функции в @mtrw ответ для больших размеров массива,
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
хотя для меньших размеров, appendSpherical_np
на самом деле быстрее,
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
Отличная работа, мое решение Cython только немного быстрее (1,23 секунды против 1,54 секунды на моей машине). По какой-то причине я не видел векторизованную функцию arctan2, когда я искал ее прямо с numpy. +1 –
Anon предложил 'ptsnew [:, 4] = np.arctan2 (np.sqrt (xy), xyz [,, 2])' –
см .: http://stackoverflow.com/edit-suggestions/756 –