2010-07-23 3 views
2

Скажем, у меня есть NumPy матрица вроде так:Оптимальное извлечение колонн из Numpy матрицы

[[ x1, x2, x3, ... ], 
[ y1, y2, y3, ... ], 
[ z1, z2, z3, ... ], 
[ 1, 1, 1, ... ]] 

Из чего я хочу, чтобы извлечь список списков как так:

[[x1, y1, z1], [x2, y2, z2], [x3, y3, z3], ... ] 

Что самое оптимальный способ сделать это?

На данный момент у меня есть:

tpoints = [pt[:3].tolist() for pt in numpy.asarray(tptmat.T)] 

И призыв к tolist() принимает на непропорционально большое количество времени, примерно треть времени, затраченного в большую часть времени функции моей программы потребления.

ncalls tottime percall cumtime percall filename:lineno(function) 
14422540 69.777 0.000 69.777 0.000 {method 'tolist' of 'numpy.ndarray' objects} 
     20 64.258 3.213 178.057 8.903 trans.py:152(_apply) 
     ... 

ответ

3

Почему бы не удалить последнюю строку перед транспонированием?

m[:3].T.tolist() 
#  ^^^^^^^^^ optional 

Micro-тест показывает этот метод быстрее, чем у вас на 61%, и если вы не превратить его в список списка это в 45 раз быстрее, для матрицы размером 100 × 4.

$ python2.5 -m timeit -s 'import numpy; m = numpy.matrix([[5]*100,[6]*100,[7]*100,[1]*100])' 'm[:3].T' 
100000 loops, best of 3: 6.26 usec per loop 
$ python2.5 -m timeit -s 'import numpy; m = numpy.matrix([[5]*100,[6]*100,[7]*100,[1]*100])' 'm[:3].T.tolist()' 
10000 loops, best of 3: 180 usec per loop 
$ python2.5 -m timeit -s 'import numpy; m = numpy.matrix([[5]*100,[6]*100,[7]*100,[1]*100])' 'numpy.asarray(m[:3].T)' 
100000 loops, best of 3: 10.9 usec per loop 
$ python2.5 -m timeit -s 'import numpy; m = numpy.matrix([[5]*100,[6]*100,[7]*100,[1]*100])' '[p[:3].tolist()for p in numpy.asarray(m.T)]' 
1000 loops, best of 3: 289 usec per loop 
+0

Отлично! И это выглядит еще лучше. У меня было ощущение, что я все усложняю. –

+0

Также, к сожалению, 'tolist()' необходимо в этом случае. Код, который я не контролирую дроссели, если я передаю ему массив numpy. –

1

Вы пытались zip(*matrix)? Это оставит вас с

[[x1, y1, z1, 1], [x2, y2, z2, 1], [x3, y3, z3, 1], ... ] 

Но поколение список, вероятно, все еще может случиться ...

Подождите (хлопает ладонью по лбу)! Это должно сделать трюк:

zip(*matrix[:3]) 

В интерактивной оболочке:

>>> matrix = [[ 11, 12, 13, 14], 
...   [ 21, 22, 23, 24], 
...   [ 31, 32, 33, 34], 
...   [ 1, 1, 1, 1]] 
>>> zip(*matrix[:3]) 
[(11, 21, 31), (12, 22, 32), (13, 23, 33), (14, 24, 34)] 
>>> 

Это список кортежей, хотя, но это действительно имеет значение?

Смежные вопросы