python可以500<x<1000_python – 为什么X.dot(X.T)在numpy中需要这么多内存?

问题不在于X和X.T本身是相同内存空间的视图,

而是X.T是F-连续而不是C-连续.当然,这必须

对于该情况中的至少一个输入阵列必然是正确的

您将数组与其转置视图相乘的位置.

在numpy< 1.8,np.dot会

创建任何F有序输入数组的C有序副本,而不仅仅是碰巧在同一块上的视图

记忆.

例如:

X = np.random.randn(1000,50000)

Y = np.random.randn(50000, 100)

# X and Y are both C-order, no copy

%memit np.dot(X, Y)

# maximum of 1: 485.554688 MB per loop

# make X Fortran order and Y C-order, now the larger array (X) gets

# copied

X = np.asfortranarray(X)

%memit np.dot(X, Y)

# maximum of 1: 867.070312 MB per loop

# make X C-order and Y Fortran order, now the smaller array (Y) gets

# copied

X = np.ascontiguousarray(X)

Y = np.asfortranarray(Y)

%memit np.dot(X, Y)

# maximum of 1: 523.792969 MB per loop

# make both of them F-ordered, both get copied!

X = np.asfortranarray(X)

%memit np.dot(X, Y)

# maximum of 1: 905.093750 MB per loop

如果复制是一个问题(例如,当X非常大时),你能做些什么呢?

最好的选择可能是升级到更新版本的numpy – 正如@perimosocordiae指出的那样,这个性能问题在this pull request中得到了解决.

如果由于某种原因你不能升级numpy,还有一个技巧,允许你执行快速,基于BLAS的点产品,而无需通过scipy.linalg.blas直接调用相关的BLAS函数强制复制(从this answer无耻地被盗) ):

from scipy.linalg import blas

X = np.random.randn(1000,50000)

%memit res1 = np.dot(X, X.T)

# maximum of 1: 845.367188 MB per loop

%memit res2 = blas.dgemm(alpha=1., a=X.T, b=X.T, trans_a=True)

# maximum of 1: 471.656250 MB per loop

print np.all(res1 == res2)

# True

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值