在Python中快速矩阵转置

4
有没有一种快速的方法在Python中对矩形2D矩阵进行转置(不涉及任何库导入)?
比如,如果我有一个数组:
X=[ [1,2,3],
    [4,5,6] ]

我需要一个数组Y,它应该是X的转置版本,因此:
Y=[ [1,4],
    [2,5],
    [3,6] ] 

有多快算快?您有速度要求吗? - Xavier Ho
3个回答

21

简单易懂: Y=zip(*X)

>>> X=[[1,2,3], [4,5,6]]
>>> Y=zip(*X)
>>> Y
[(1, 4), (2, 5), (3, 6)]

编辑: 为了回答评论中关于zip(*X)是什么意思的问题,以下是来自Python手册的示例:

>>> range(3, 6)             # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)            # call with arguments unpacked from a list
[3, 4, 5]

因此,当X[[1,2,3],[4,5,6]]时,zip(*X)就是zip([1,2,3],[4,5,6])


在Python文档中阅读有关zip()的更多信息:http://docs.python.org/library/functions.html - unbeli
星号的作用是什么? - psihodelia
为什么是zip(*X)而不是zip(X)?抱歉我是Python新手。我知道zip(X)不能正常工作,但我不明白为什么。 - mr popo
@psihodelia, @mr popo:*是解包语法。请参阅:http://docs.python.org/tutorial/controlflow.html#unpacking-argument-lists - Xavier Ho
zip(X) 表示运行 zip(),从列表 X 中获取参数。 zip([a,b]) 等同于 zip(a,b),对于上面的 X,zip(*X) 等同于 zip([1,2,3], [4,5,6])。 - unbeli

6
>>> X = [1,2,3], [4,5,6]]
>>> zip(*X)
[(1,4), (2,5), (3,6)]
>>> [list(tup) for tup in zip(*X)]
[[1,4], [2,5], [3,6]]

如果内部对需要是列表,那就选择第二个。

考虑使用 izip() 作为第二个参数,它可能会更快。 :] - Xavier Ho
@Xavier,想象某些东西更快并不是我们优化代码的方式。事实证明,我们猜错的次数比我们想象的要多得多。实际上,我不确定,但从经验上来看,对于许多输入,zip形式实际上会更快,尽管需要更多的内存。无论如何,玩弄这两个选项并不是提高此操作性能的方法。 - Mike Graham
@Mike:是的,你说得对。但是我的经验告诉我,在大输入时,range()通常比xrange()慢,因为分配内存需要时间。虽然我不能确定列表推导式是否有任何优化,但我能给出的最好跟进评论是进行性能分析 - 这是唯一找出答案的方法。 - Xavier Ho
2
@Mike:如果你感兴趣的话,我刚刚做了一个快速基准测试。当矩阵大小约为1000x1000时,izip()开始胜出。因此,如果大多数矩阵输入的维度小于该值,则zip()非常好用。(Python 2.6.5) - Xavier Ho

5
如果你正在处理矩阵,那么几乎肯定需要使用 numpy。这将比纯Python代码更轻松、更高效地执行数值操作。
>>> x = [[1,2,3], [4,5,6]]
>>> x = numpy.array(x)
>>> x
array([[1, 2, 3],
       [4, 5, 6]])
>>> x.T
array([[1, 4],
       [2, 5],
       [3, 6]])

“不涉及任何库导入”是一个愚蠢、无生产力的要求。

这不应该是一条回答,而应该是一条注释,@Mike? - Xavier Ho
好的,只是确认一下你的意图。我也会使用numpy,而且速度会更快。 - Xavier Ho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接