Python中转置函数的区别

8

我正在生成一个大矩阵(100x100,我们称之为X),其中包含随机数字,使用numpy.matrix()使其成为numpy.ndarray。

我一直在想这两个操作之间是否有区别:

  1. numpy.transpose(X)
  2. X.T

我用1000的范围内循环测量了每个操作的时间,结果表明X.Tnumpy.transpose(X)快得多。

添加基准测试:

对于一个100x100的矩阵,我通过X.Tnumpy.tranpose(X)获得了以下结果:

在10,000范围内循环:

  • 7421/10,000: X.T最快
  • 1256/10,000: numpy.transpose(X)最快
  • 1323/10,000: 相同的计算时间或差异太小无法确定

添加以下代码:

    import numpy as np
    import time

    np_transpose_count = 0
    T_transpose_count = 0
    equal_count = 0

    for i in range(10000):
       Se = np.random.rand(100,100)

       tic1 =time.clock()
       ST_T = Se.T
       toc1=time.clock()

       tic2 =time.clock()
       ST_np = np.transpose(Se)
       toc2=time.clock()

       if (toc1-tic1) < (toc2-tic2):
           T_transpose_count+=1
       elif (toc1-tic1) > (toc2-tic2):
           np_transpose_count+=1
       else:
           equal_count+=1

    print(T_transpose_count, np_transpose_count, equal_count)

敬祝商祺 Whir


有趣。我不理解你基准测试的单位。你能更新一下吗?在我的系统上,看起来 X.T 比 X.transpose() 快20-30%(使用 %timeit 在100x100或10000x10000数组上)。 - user20160
2
此外,在我的系统上,np.transpose(X)x.T 慢了 120-130%。也许函数调用会有一些额外的开销(x.transpose() 是一个函数,而 x.T 不是)。np.transpose() 是一个带有一些包装代码的 Python 函数,因此存在一些额外的开销。 - user20160
1个回答

9

使用IPython的%timeit魔法命令,我得到了以下结果:

In [218]: X=np.ones((100,100))

In [219]: timeit X.T
1000000 loops, best of 3: 379 ns per loop

In [220]: timeit X.transpose()
1000000 loops, best of 3: 470 ns per loop

In [221]: timeit np.transpose(X)
1000000 loops, best of 3: 993 ns per loop

In [222]: timeit X+1
10000 loops, best of 3: 21.6 µs per loop

所以,是的,.T 是最快的,而函数是最慢的。但将这些时间与简单加法的时间进行比较。
或者复制或切片的时间。
In [223]: timeit X.copy()
100000 loops, best of 3: 10.8 µs per loop

In [224]: timeit X[:]
1000000 loops, best of 3: 465 ns per loop

转置在所有形式中都返回一个新的数组对象,具有新的shapestrides,但共享数据缓冲区(查看.__array_interface__字典)。因此,它需要与返回view的其他操作大致相同的时间。但是,没有任何转置函数会复制数据或迭代数据。因此,时间差异只是调用开销的结果。

再次使用ipython魔法

np.transpose??
def transpose(a, axes=None):
    try:
        transpose = a.transpose
    except AttributeError:
        return _wrapit(a, 'transpose', axes)
    return transpose(axes)

因此,np.function(X)最终会调用X.transpose()

我需要查看numpy的代码,但我记得.T被实现为一个属性(不完全相同于属性)。 我怀疑它更快,因为它不使用axes参数,从而节省了一个或两个C函数调用。


感谢您的详细回复。对于我理解这个问题非常有帮助。 - Whir

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