Python 在最后一个轴上结合外部减法和元素减法?

Python 在最后一个轴上结合外部减法和元素减法?,python,numpy,numpy-ufunc,Python,Numpy,Numpy Ufunc,考虑上面的代码。我有一个形状为(4,4,4,16,3)的数组A,它表示晶格中的三维位置向量(dim 3的最后一个轴是x,y,z坐标)。前4个维度索引晶格中的位置 我想要什么 我想从A生成一个数组,其中包含晶格中站点之间所有可能的分离向量。这意味着输出数组B,其形状(4,4,4,16,4,4,4,16,3)。前4个维度是位置i,后4个维度是位置j,然后是位置向量差的(x,y,z)坐标的最后一个维度 i、 e.A[A,b,c,d]:形状(3,)是第一个位置的(x,y,z)A[r,s,t,u]:形状(

考虑上面的代码。我有一个形状为(4,4,4,16,3)的数组
A
,它表示晶格中的三维位置向量(dim 3的最后一个轴是x,y,z坐标)。前4个维度索引晶格中的位置

我想要什么 我想从
A
生成一个数组,其中包含晶格中站点之间所有可能的分离向量。这意味着输出数组
B
,其形状
(4,4,4,16,4,4,4,16,3)
。前4个维度是位置i,后4个维度是位置j,然后是位置向量差的(x,y,z)坐标的最后一个维度

i、 e.
A[A,b,c,d]
:形状(3,)是第一个位置的(x,y,z)<代码>A[r,s,t,u]:形状(3,)是第二个位置的(x,y,z);然后我希望
B[a,B,c,d,r,s,t,u]
是前两者之间的(x,y,z)差

我的尝试 我知道
ufunc.outer
函数,您可以在我的代码尝试中看到这一点。但我一直在应用它,并在每个
A
的最后一个轴(x,y,z))上执行元素级减法


在我的尝试中,
B
具有我想要的正确维度,但它显然是错误的。有什么提示吗?(除非使用任何for循环)

我认为您只需要执行以下操作:

import numpy as np
import itertools as it

SPIN_POS = np.array([[0, 0, 0], [1, 1, 0], [1, 0, 1], [0, 1, 1],  
                     [2, 2, 0], [3, 3, 0], [3, 2, 1], [2, 3, 1], 
                     [2, 0, 2], [3, 1, 2], [3, 0, 3], [2, 1, 3],  
                     [0, 2, 2], [1, 3, 2], [1, 2, 3], [0, 3, 3] 
                     ]) / 4

def gen_posvecs(xdim:int, ydim:int, zdim:int):
    """
    Generates position vectors of site pairs in the lattice of size xdim,ydim,zdim

    :param x,y,z is the number of unit cells in the x,y,z directions;
    :returns array containing the position vectors
    """
    poss = np.zeros((xdim,ydim,zdim,16,3))
    for x,y,z,s in it.product(range(xdim), range(ydim), range(zdim), range(16)):
        poss[x,y,z,s] = np.array([x,y,z]) + SPIN_POS[s]
    return poss

A = gen_sepvecs(4,4,4)  # A.shape = (4,4,4,16,3)
B = np.subtract.outer(A[...,-1], A)  # my attempt at a soln
assert all(A[1,2,0,12] - A[0,1,3,11] == B[1,2,0,12,0,1,3,11])  # should give true
在代码中:

B = (A[:, :, :, :, np.newaxis, np.newaxis, np.newaxis, np.newaxis] -
     A[np.newaxis, np.newaxis, np.newaxis, np.newaxis])

是的,我想那是对的。我本应该恢复正常的广播。。谢谢(+1)。在接受这个问题之前,我会多留一点时间,希望你同意
import numpy as np
import itertools as it

SPIN_POS = np.array([[0, 0, 0], [1, 1, 0], [1, 0, 1], [0, 1, 1],  
                     [2, 2, 0], [3, 3, 0], [3, 2, 1], [2, 3, 1], 
                     [2, 0, 2], [3, 1, 2], [3, 0, 3], [2, 1, 3],  
                     [0, 2, 2], [1, 3, 2], [1, 2, 3], [0, 3, 3] 
                     ]) / 4

def gen_posvecs(xdim:int, ydim:int, zdim:int):
    """
    Generates position vectors of site pairs in the lattice of size xdim,ydim,zdim

    :param x,y,z is the number of unit cells in the x,y,z directions;
    :returns array containing the position vectors
    """
    poss = np.zeros((xdim,ydim,zdim,16,3))
    for x,y,z,s in it.product(range(xdim), range(ydim), range(zdim), range(16)):
        poss[x,y,z,s] = np.array([x,y,z]) + SPIN_POS[s]
    return poss

A = gen_posvecs(4,4,4)  # A.shape = (4,4,4,16,3)
B = A[:, :, :, :, np.newaxis, np.newaxis, np.newaxis, np.newaxis] - A[np.newaxis, np.newaxis, np.newaxis, np.newaxis]

assert all(A[1,2,0,12] - A[0,1,3,11] == B[1,2,0,12,0,1,3,11])
# Does not fail