I have 5 multidimensional arrays
A = [ [1,2,3,4,5,6]
[3,4,5,6,7,8]
[5,6,7,8,9,0] ]
B = [ [11,12,13,14,15,16]
[21,22,23,24,25,26]
[13,14,15,16,17,18] ]
C = [ [31,32,33,34,35,36]
[12,13,14,15,16,17]
[20,21,22,23,24,25] ]
D = [ [2,3,4,5,6,7]
[3,4,5,6,7,8]
[6,7,8,9,0,11] ]
Base = [ [11,22,33,44,55,66]
[12,23,34,45,56,67]
[33,44,55,66,77,88]
[1,2,3,4,5,6] ]
So I want to multiply the array A, B, C, and D by the Base array. Which will produce output like the following
Output = [ [A[0]*Base[0] B[0]*Base[1] C[0]*Base[2] D[0]*Base[3] ], (this is summed)
[A[1]*Base[0] B[1]*Base[1] C[1]*Base[2] D[1]*Base[3] ], (this is summed)
[A[2]*Base[0] B[2]*Base[1] C[2]*Base[2] D[2]*Base[3] ], (this is summed)
[A[3]*Base[0] B[3]*Base[1] C[3]*Base[2] D[3]*Base[3] ] (this is summed)
]
what I've been trying to do is to use an algorithm like the following. Multiply them one by one,
Output 1 = A*Base[0]
Output 2 = B*Base[1]
Output 3 = C*Base[2]
Output 4 = D*Base[3]
then add them up one by one
Sum1 = sum(Output1[0])
Sum2 = sum[Output1[1])
Sum3 = sum(Output1[2])
Sum4 = sum(Output2[0])
Sum5 = sum(Output2[1])
...
...
...
...
So I get the output by adding them up : [Sum1 Sum4 .....], [Sum2 Sum5 ....]....
Is there a simpler and shorter way to do this, apart from multiplying them one by one?
Sorry I'm just learning to use python. Please help Thank you
CodePudding user response:
It's not very clear what operation result you want with multiplying arrays, but just use numpy to make your life easier.
A, B, C, D, Base = np.array(A), np.array(B), np.array(C), np.array(D), np.array(Base)
For instance, the following operation multiplies and sum A * Base resulting in 4 * 3 sum arrays:
[sum(list(base_list * A_list)) for base_list in Base for A_list in A]
[1001, 1463, 1265, 1022, 1496, 1300, 1463, 2189, 2035, 91, 133, 115]
Then just sum the results to obtain the full sum of A*Base in 1/2 lines (and do the same with the remaining ones)
sum([1001, 1463, 1265, 1022, 1496, 1300, 1463, 2189, 2035, 91, 133, 115])
13573
CodePudding user response:
numpy is really useful for this type of operation. Here a code snippet for what you want to do:
import numpy as np
A = [[1, 2, 3, 4, 5, 6],
[3, 4, 5, 6, 7, 8],
[5, 6, 7, 8, 9, 0]]
B = [[11, 12, 13, 14, 15, 16],
[21, 22, 23, 24, 25, 26],
[13, 14, 15, 16, 17, 18]]
C = [[31, 32, 33, 34, 35, 36],
[12, 13, 14, 15, 16, 17],
[20, 21, 22, 23, 24, 25]]
D = [[2, 3, 4, 5, 6, 7],
[3, 4, 5, 6, 7, 8],
[6, 7, 8, 9, 0, 11]]
Base = [
[11, 22, 33, 44, 55, 66],
[12, 23, 34, 45, 56, 67],
[33, 44, 55, 66, 77, 88],
[1, 2, 3, 4, 5, 6]
]
A = np.asarray(A)
B = np.asarray(B)
C = np.asarray(C)
D = np.asarray(D)
Base = np.asarray(Base)
Output = np.asarray([
[A[0] * Base[0] B[0] * Base[1] C[0] * Base[2] D[0] * Base[3]],
[A[1] * Base[0] B[1] * Base[1] C[1] * Base[2] D[1] * Base[3]],
[A[2] * Base[0] B[2] * Base[1] C[2] * Base[2] D[2] * Base[3]],
# [A[3] * Base[0] B[3] * Base[1] C[3] * Base[2] D[3] * Base[3]] # IndexError: index 3 is out of bounds for axis 0 with size 3 -> the matrices A, B, C and D have only 3 rows
]).squeeze()
print(f"{A.shape = } {B.shape = } {C.shape = } {D.shape = } {Base.shape = }, {Output.shape = }")
# simple math
results_simple = A * Base[0] B * Base[1] C * Base[2] D * Base[3]
print(f"{results_simple.shape = }")
print(f"{np.allclose(results_simple, Output) = }")
# result with more algebra
M = np.stack([A, B, C, D], axis=1)
print(f"{M.shape = }")
results_algebra = np.sum(M * Base, axis=1)
print(f"{results_algebra.shape = }")
print(f"{np.allclose(results_algebra, Output) = }")
# results with einsum
results_einsum = np.einsum("ijk,jk->ik", M, Base)
print(f"{results_einsum.shape = }")
print(f"{np.allclose(results_einsum, Output) = }")
out:
A.shape = (3, 6) B.shape = (3, 6) C.shape = (3, 6) D.shape = (3, 6) Base.shape = (4, 6), Output.shape = (3, 6)
results_simple.shape = (3, 6)
np.allclose(results_simple, Output) = True
M.shape = (3, 4, 6)
results_algebra.shape = (3, 6)
np.allclose(results_algebra, Output) = True
results_einsum.shape = (3, 6)
np.allclose(results_einsum, Output) = True
After this, you can get the sum of the output in a certain axis using the function numpy.sum. You will have something like this:
out_sum = np.sum(Output, axis=-1)