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

如何有效地扩展numpy中的因子张量?

  •  1
  • capybaralet  · 技术社区  · 10 年前

    我将一个三维张量分解为三个二维矩阵,如本文中的方程22: http://www.iro.umontreal.ca/~memisevr/pubs/pami_relational.pdf

    我的问题是,如果我想明确地计算张量,有没有比numpy更好的方法?

    W = np.zeros((100,100,100))
    for i in range(100):
        for j in range(100):
            for k in range(100):
                W[i,j,k] = np.sum([wxf[i,f]*wyf[j,f]*wzf[k,f] for f in range(100)]) 
    
    2 回复  |  直到 10 年前
        1
  •  2
  •   DSM    10 年前

    我倾向于使用 einsum 因为这通常是最容易写的:

    def fast(wxf, wyf, wzf):
        return np.einsum('if,jf,kf->ijk', wxf, wyf, wzf)
    
    def slow(wxf, wyf, wzf):
        N = len(wxf)
        W = np.zeros((N, N, N))
        for i in range(N):
            for j in range(N):
                for k in range(N):
                    W[i,j,k] = np.sum([wxf[i,f]*wyf[j,f]*wzf[k,f] for f in range(N)]) 
        return W
    
    def gen_ws(N):
        wxf = np.random.random((N,N))
        wyf = np.random.random((N,N))
        wzf = np.random.random((N,N))
        return wxf, wyf, wzf
    

    给予

    >>> ws = gen_ws(25)
    >>> via_slow = slow(*ws)
    >>> via_fast = fast(*ws)
    >>> np.allclose(via_slow, via_fast)
    True
    

    >>> ws = gen_ws(100)
    >>> %timeit fast(*ws)
    10 loops, best of 3: 91.6 ms per loop
    
        2
  •  1
  •   Saullo G. P. Castro    10 年前

    通过您的示例,可以非常简单地使用 np.einsum() :

    W = np.einsum('ij,jf,kf->ijk', wxf, wyf, wzf)