使用numpy数组向量化函数

布劳弗

我试图加快我编写的某些代码的速度,但是这样做却有很多麻烦。我知道能够删除for循环并使用numpy可以帮助实现这一点,因此我一直在尝试但收效甚微。

没有任何加速的工作功能是

def acf(x, y, z, cutoff=0):
    steps = x.shape[1]
    natoms = x.shape[0]

    z_x = np.zeros((steps,natoms))
    z_y, z_z = np.zeros_like(z_x), np.zeros_like(z_x)

    xmean = np.mean(x, axis=1)
    ymean = np.mean(y, axis=1)
    zmean = np.mean(z, axis=1)

    for k in range(steps-cutoff): # x.shape[1]
        xtemp, ytemp, ztemp = [], [], []
        for i in range(x.shape[0]): # natoms
            xtop, ytop, ztop = 0.0, 0.0, 0.0
            xbot, ybot, zbot = 0.0, 0.0, 0.0
            for j in range(steps-k): # x.shape[1]-k
                xtop += (x[i][j] - xmean[i]) * (x[i][j+k] - xmean[i])
                ytop += (y[i][j] - ymean[i]) * (y[i][j+k] - ymean[i])
                ztop += (z[i][j] - zmean[i]) * (z[i][j+k] - zmean[i])
                xbot += (x[i][j] - xmean[i])**2
                ybot += (y[i][j] - ymean[i])**2
                zbot += (z[i][j] - zmean[i])**2
            xtemp.append(xtop/xbot)
            ytemp.append(ytop/ybot)
            ztemp.append(ztop/zbot)
        z_x[k] = xtemp
        z_y[k] = ytemp
        z_z[k] = ztemp

    z_x = np.mean(np.array(z_x), axis=1)
    z_y = np.mean(np.array(z_y), axis=1)
    z_z = np.mean(np.array(z_z), axis=1)

    return z_x, z_y, z_z

此函数的输入x,y和z是相同维的numpy数组。x(或y或z)的一个示例是:

x = np.array([[1,2,3],[4,5,6]])

到目前为止,我能够做的是

def acf_quick(x, y, z, cutoff=0):
    steps = x.shape[1]
    natoms = x.shape[0]

    z_x = np.zeros((steps,natoms))
    z_y, z_z = np.zeros_like(z_x), np.zeros_like(z_x)

    x -= np.mean(x, axis=1, keepdims=True)
    y -= np.mean(y, axis=1, keepdims=True)
    z -= np.mean(z, axis=1, keepdims=True)

    for k in range(steps-cutoff): # x.shape[1]
        for i in range(natoms):
            xtop, ytop, ztop = 0.0, 0.0, 0.0
            xbot, ybot, zbot = 0.0, 0.0, 0.0
            for j in range(steps-k): # x.shape[1]-k
                xtop += (x[i][j]) * (x[i][j+k])
                ytop += (y[i][j]) * (y[i][j+k])
                ztop += (z[i][j]) * (z[i][j+k])
                xbot += (x[i][j])**2
                ybot += (y[i][j])**2
                zbot += (z[i][j])**2
            z_x[k][i] = xtop/xbot
            z_y[k][i] = ytop/xbot
            z_z[k][i] = ztop/xbot

    z_x = np.mean(np.array(z_x), axis=1)
    z_y = np.mean(np.array(z_y), axis=1)
    z_z = np.mean(np.array(z_z), axis=1)

    return z_x, z_y, z_z

这样可以将速度提高约33%,但我相信有一种方法可以消除的for i in range(natoms)使用方法x[:][j]到目前为止,我一直没有成功,任何帮助将不胜感激。

在有人问之前,我知道这是一个自相关函数,并且在numpy,scipy等中内置了一些函数,但是我需要自己编写。

sltzgs

这是循环的矢量化形式:

def acf_quick_new(x, y, z, cutoff=0):
    steps = x.shape[1]
    natoms = x.shape[0]

    lst_inputs = [x.copy(),y.copy(),z.copy()]
    lst_outputs = []
    for x_ in lst_inputs:

        z_x_ = np.zeros((steps,natoms))

        x_ -= np.mean(x_, axis=1, keepdims=True)

        x_top = np.diag(np.dot(x_,x_.T))
        x_bot = np.sum(x_**2, axis=1)

        z_x_[0,:] = np.divide(x_top, x_bot)


        for k in range(1,steps-cutoff): # x.shape[1]

            x_top = np.diag(np.dot(x_[:,:-k],x_.T[k:,:]))
            x_bot = np.sum(x_[:,:-k]**2, axis=1)

            z_x_[k,:] = np.divide(x_top, x_bot)


        z_x_ = np.mean(np.array(z_x_), axis=1)
        lst_outputs.append(z_x_)    

    return lst_outputs

请注意,在_quick函数中有一个小错误:始终按xbot而不是xbot,ybot和zbot进行划分。而且,我的建议可以写得更好一些,但是它应该可以解决您的问题并加快计算速度:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用Numpy向量化标量函数调用

来自分类Dev

如何使用NumPY向量化缩小函数?

来自分类Dev

向量化数组的函数

来自分类Dev

使用数组参数向量化函数

来自分类Dev

numpy向量化多维函数

来自分类Dev

numpy数组的向量化操作

来自分类Dev

向量化numpy数组扩展

来自分类Dev

使用numpy向量化else-if语句函数

来自分类Dev

Python:如何使用Numpy向量化我的split函数

来自分类Dev

使用Numpy向量化循环

来自分类Dev

使用Numpy向量化的循环

来自分类Dev

numpy向量化函数的返回dtype

来自分类Dev

numpy向量化数组的最大值

来自分类Dev

在numpy数组上向量化python循环

来自分类Dev

Numpy数组上的向量化计算

来自分类Dev

numpy向量化数组的最大值

来自分类Dev

向量化计数 2 维 Numpy 数组

来自分类Dev

尝试使用numpy向量化迭代计算

来自分类Dev

使用numpy向量化方程式

来自分类Dev

使用 numpy 向量化逐行添加?

来自分类Dev

熊猫在用户定义的函数中使用Numpy向量化,而不是使用loops / lambda.apply()

来自分类Dev

使用numpy数组的条件向量化计算,而无需使用直接掩码

来自分类Dev

如何使用if语句向量化在numpy数组中查找最大值?

来自分类Dev

向量化numpy分配

来自分类Dev

向量化python函数

来自分类Dev

向量化数组访问

来自分类Dev

向量化数组索引

来自分类Dev

向量化数组访问

来自分类Dev

嵌套循环Numpy数组:可以向量化吗?