Python大数据矩阵操作

eve*_*mer 5 python numpy matrix

我想我有一个大数据(N = 1e6和维度= 3)的情况.我需要在我的代码中多次执行一些矩阵操作,例如einsum,矩阵反转等.提出一个想法,我想做下面的事情.

import numpy.random as rd

ndata, kdata = 1e6, 1e5

x = rd.normal(0,1,(ndata, kdata,3,3))

y = rd.normal(0,1,(ndata, kdata,3,3))
Run Code Online (Sandbox Code Playgroud)

对于小ndata,kdata以下将是高效和方便的方法,

xy =  einsum('pqrs, pqsu -> pqru', x, y )
Run Code Online (Sandbox Code Playgroud)

由于我有大的ndata和kdata以上方法成为内存绑定问题所以下一个赌注将是嵌套for循环ndata和kdata的点积,如下所示:

xyloop1 = np.empty((ndata, kdata, 3, 3))

for j in xrange(ndata):

    for k in xrange(kdata):

        xyloop1[j,k] =  np.dot(x[j,k], y[j,k] )
Run Code Online (Sandbox Code Playgroud)

鉴于我所教授的循环在python中是令人讨厌的.此外,我想使用numpy的好处,所以思想块矩阵方法将是更好的事情如下:

nstep = 200
ndiv  = ndata/nstep   

kstep = 200
kdiv  = kdata/kstep   

xyloop2 = np.empty((ndata, kdata, 3, 3))

for j in xrange(ndiv):

    ji, jf = j*nstep, (j+1)*nstep     

    for k in xrange(kdiv):

        ki, kf = k*kstep, (k+1)*kstep     

        xyloop2[ji:jf,ki:kf] =  einsum('pqrs, pqsu -> pqru', x[ji:jf,ki:kf], y[ji:jf,ki:kf] )
Run Code Online (Sandbox Code Playgroud)

另外,我需要这些xy或xyloop1或xyloop2进行进一步计算.所以我必须在每次计算后编写并读取它.考虑到系统I/O的带宽,你认为最好的方法是接近3,因为与方法2相比,它意味着更少的I/O和少量的迭代?如果您有任何其他想法或需要更多信息,请告诉我.

我是新手,所以请对我温柔:)​​.任何帮助将受到高度赞赏.顺便说一下,我正在尝试解决大数据的混合建模问题.谢谢!

kiy*_*iyo 2

虽然我同意这样的评论,即唯一确定的方法是为自己进行概要分析,但有一些指导原则可以帮助您numpy在第一次尝试时编写高效的代码。针对您的问题,以下是一些建议:

  • 创建新的 numpy 数组的开销是加法/乘法成本的 1000 倍,因此方法 2 应该效率很低,因为每次调用都会np.dot创建一个数组,但只执行 27 次加法/乘法。
  • 如果要在 python 中使用缓慢的 for 循环,请尽可能在最左边的轴上进行(对于 C 有序数组)。
  • 高效地编写非常通用的 N 维代码非常困难,所以我的猜测是,一系列numpy更简单的调用将比np.einsum. 尝试一下C = np.sum(A[...,:,None] * B[...,:,:], axis=-2)(尽管这是相当推测的)。

所以我会尝试如下所示:

xyloop2 = np.empty((ndata, kdata, 3, 3))

for i in xrange(ndata):
    xyloop2[i] = np.sum(x[i,:,:,:,None] * y[i,:,None,:,:], axis=-2)
Run Code Online (Sandbox Code Playgroud)

与方法 2 类似,但 for 循环更简单(也更高效)。还把矩阵乘法换成了我认为可能更快的东西。