Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 4d阵列处理(使用einsum?)_Python_Numpy_Matrix_Multidimensional Array_Numpy Einsum - Fatal编程技术网

Python 4d阵列处理(使用einsum?)

Python 4d阵列处理(使用einsum?),python,numpy,matrix,multidimensional-array,numpy-einsum,Python,Numpy,Matrix,Multidimensional Array,Numpy Einsum,我有一个基于矩阵的问题,我认为可以用numpy(也许是einsum?)在一行代码中解决(计算成本很低),但无法找到解决方案 我想知道是否有人能提出一些建议?问题如下: A = 4d array of shape: (5, 5, 5, 5) M = 2d array of shape: (100, 5) Target result, R = 2d array of shape (100, 5) where... R[z, p] = sum for p having values of [i, j

我有一个基于矩阵的问题,我认为可以用numpy(也许是einsum?)在一行代码中解决(计算成本很低),但无法找到解决方案

我想知道是否有人能提出一些建议?问题如下:

A = 4d array of shape: (5, 5, 5, 5)
M = 2d array of shape: (100, 5)

Target result, R = 2d array of shape (100, 5) where...
R[z, p] = sum for p having values of [i, j, k, l] over: A[i,j,k,l] * M[z,i] * M[z, j] * sgn[p]

where sgn[p] = -ve if p = i or j; +ve if p = k or l
例如:

# Enter two values in A array
A = np.zeros([5, 5, 5, 5])
A[2, 1, 3, 0] = 1
A[2, 2, 4, 1] = 1

M = np.zeros([100, 5])
M[None, :] = np.arange(5)  # fill with dummy data

R = SOLUTION_FUNC(A, M), computed as:

# For R[:, 0] there's only one term to add
# since 0 only appears once as an index for non-zero values in the A array.
# As 0 appears in second half of the index set, we keep the value positive
R[z, 0] = A[2, 1, 3, 0] * M[z, 2] * M[z, 1]

# For R[:, 1], we add both terms in A since 1 appears as an index in both non-zero values
# As 1 is in first half of the list the first time, we make this value negative
R[z, 1] = -1 * A[2, 1, 3, 0] * M[z, 2] * M[z, 1] + A[2, 2, 4, 1] * M[z, 2] * M[z,2]

# For R[z:, 2], there are three terms to add since 2 appears as a 
# non-zero index three times in the A matrix.
# The 2 always appears in first half of list, so we make all terms negative
R[z, 2] = -1* A[2, 1, 3, 0] * M[z, 2] * M[z, 1] + -1*A[2, 2, 4, 1] * M[z, 2] * M[z,2] + -1 * A[2, 2, 4, 1] * M[z, 2] * M[z,2]

# etc....
R[z, 3] = A[2, 1, 3, 0] * M[z, 2] * M[z, 1]
R[z, 4] = A[2, 2, 4, 1] * M[z, 2] * M[z, 2]
如果有帮助的话,A是相对稀疏的(可能包含<20个非零项-但这些项可以位于任意随机位置)

编辑:添加循环 我可以使用嵌套循环实现这一点,但这似乎是一个糟糕的解决方案:

length = 5
A = np.zeros([length, length, length, length])
A[2, 1, 3, 0] = 1
A[2, 2, 4, 1] = 2

M = np.zeros([100, length])
M[None, :] = np.arange(length) + 1 # fill with dummy data

result = np.zeros_like(M, dtype=float)

# Many loop solution
non_zero_indexes = np.array(np.nonzero(A)).T

for z in range(len(M)):
    for non_zero_index_set in non_zero_indexes:
        for i in range(length):
            # The set indices are inspected in two halves: if i in first half, return negative value
            if i in non_zero_index_set[:2]:
                # If a number appears twice in the list, we need to add twice, so include a factor
                factor = -1 * list(non_zero_index_set).count(i)  # negative factor
                result[z, i] += factor * A[non_zero_index_set[0], non_zero_index_set[1], non_zero_index_set[2], non_zero_index_set[3]]   \
                                 * M[z, non_zero_index_set[0]] * M[z, non_zero_index_set[1]]
            elif i in non_zero_index_set[-2:]:
                factor = +1 * list(non_zero_index_set).count(i)  # positive factor
                result[z, i] += factor * A[non_zero_index_set[0], non_zero_index_set[1], non_zero_index_set[2], non_zero_index_set[3]]   \
                                 * M[z, non_zero_index_set[0]] * M[z, non_zero_index_set[1]]
我已经尝试了大量的
einsum
排列,我认为这可能能够解决这个问题。e、 g.形式为
np.einsum('ijkl,mi->mi')
,但以某种方式包括上述所有ijkl的总和


希望这是有意义的,任何指针(或使用einsum/其他数组处理路径的进一步建议)都会非常好

分享您基于工作循环的解决方案?谢谢,这是一个很好的建议。我现在添加了这个,并澄清了问题。欢迎任何建议,谢谢!如果可能的话,你应该试着在跑步之前先走路:你能在3维或更小的维度上模拟你的问题吗?我还没有弄清楚那是什么,但我想知道它是否有点像克罗内克三角洲。增量值为1/0,而这是-1/1。因此,与其将is定义为“函数”,不如将其定义为多维数组?能否将
a[i,j,k,l]*M[z,i]*M[z,j]
表示为
einsum
?该总和是否在
i
j
上?在
z
上<代码>'ijkl,zi,zj->kl'或
zkl
或其他什么?