从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)
...
2 个回答
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)]
>>>
不过,这个结果是一个元组的列表,这真的重要吗?
3
为什么不在转置之前先去掉最后一行呢?
m[:3].T.tolist()
# ^^^^^^^^^ optional
微基准测试显示,这种方法比你的快61%,如果不把它转换成列表的列表,那对于一个100×4的矩阵来说,它快了45倍。
$ 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