代码之家  ›  专栏  ›  技术社区  ›  mikanim

改进二维余弦函数的numpy功能

  •  0
  • mikanim  · 技术社区  · 1 年前

    1. 改进numpy代码,使代码运行更快(即不用于循环)

    import numpy as np
    
    k = np.linspace(0,4.76*10,2400)
    kx,ky = np.meshgrid(k, k)
    
    rx = [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]
    ry = [0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2]
    
    tensx = np.tensordot(rx,kx, axes = 0)
    tensy = np.tensordot(ry,ky, axes = 0)
    z = 0
    
    for i in range(0, len(tensx)):
        z = z + 0.05*np.cos(2*np.pi*(tensx[i]+tensy[i]))
    

    代码当前不可用 缓慢的

    非常感谢您的帮助!

    1 回复  |  直到 1 年前
        1
  •  0
  •   Nin17    1 年前

    0.05*np.cos(2*np.pi*(tensx+tensy[:-1])).sum(axis=0)
    

    或者更一般地说:

    0.05*np.cos(2*np.pi*(tensx+tensy[:tensx.shape[0]])).sum(axis=0)
    

    您也可以避免 meshgrid ,避免计算未使用的元素 tensy

    tensx = np.tensordot(rx, k[None, :], axes=0)
    tensy = np.tensordot(ry[:len(rx)], k[:, None], axes=0)
    

    def op():
        k = np.linspace(0,4.76*10,2400)
        kx,ky = np.meshgrid(k, k)
    
        rx = [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]
        ry = [0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2]
    
        tensx = np.tensordot(rx,kx, axes = 0)
        tensy = np.tensordot(ry,ky, axes = 0)
        z = 0
        for i in range(0, len(tensx)):
            z = z + 0.05*np.cos(2*np.pi*(tensx[i]+tensy[i]))
        return z
    
    def Nin17():
        k = np.linspace(0,4.76*10,2400)
    
        rx = [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]
        ry = [0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2]
        tensx = np.tensordot(rx, k[None, :], axes=0)
        tensy = np.tensordot(ry[:len(rx)], k[:, None], axes=0)
        return 0.05*np.cos(2*np.pi*(tensx+tensy)).sum(axis=0)
    
    assert np.isclose(Nin17(), op()).all()
    %timeit Nin17()
    %timeit op()
    

    输出:

    359 ms ± 2.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    410 ms ± 5.47 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)