Самый быстрый способ конвертировать трехмерные координаты из строки в плавающий массив - PullRequest
1 голос
/ 22 октября 2019

У меня есть 3D-координаты (строки) в списке, который я хотел бы преобразовать в массивы с плавающей точкой.

# current list
iPoints = ['-50.0651394154927,-5.3133315588409,0', '-48.7824404616692,3.1894817418136,0', '-46.2317402190515,11.3986203175639,0']

# ideal output
array([[-50.0651394154927,-5.3133315588409,0], [-48.7824404616692,3.1894817418136,0], [-46.2317402190515,11.3986203175639,0]])

Наивная реализация:

iPoints = np.array([[float(c) for c in v.split(',')] for v in iPoints])

Что будетсамый быстрый способ преобразовать этот список строк в массив массивов?

1 Ответ

1 голос
/ 22 октября 2019

Оригинальное решение на удивление быстро, но может быть сделано быстрее. Вы можете объединить строки в один большой буфер и обработать его одним вызовом np.fromstring.

Попробуйте следующий код:

# put everthing to a buffer as a large 1D-array separated with commas
buf = ','.join(iPoints)
# parse the buffer
iPoints = np.fromstring(buf, sep=',', dtype=float, count=3*len(iPoints))
# make it 3d again
iPoints = iPoints.reshape(-1,3)

Я сделал несколько тестов.

iPoints=['-50.0651394154927,-5.3133315588409,0', '-48.7824404616692,3.1894817418136,0', '-46.2317402190515,11.3986203175639,0']
# lets make it a little large
iMorePoints = iPoints * 10000

method1 = lambda: np.array([[float(c) for c in v.split(',')] for v in iMorePoints])
method2 = lambda: np.fromstring(','.join(iMorePoints), sep=',', dtype=float, count=3*len(iMorePoints)).reshape(-1,3)

Результаты на моей машине:

>>> timeit(method1, number=100)
3.6391940720000093
>>> timeit(method2, number=100)
1.0472392480000963

Таким образом, предлагаемое решение в 3,5 раза быстрее. Небольшой недостаток заключается в том, что нужно заранее знать, что векторы являются трехмерными. Но это можно проверить по телефону iPoints[0].count(',')+1.

...