0

I want to multiply each elements of 1dArray and each matrices of 3dArray without for loop.

arr1d2=np.array([1,2])
arr3d222=np.array([[[1,2],[3,4]],[[5,6],[7,8]]])

# Correct Solution is below
for i1 in range(len(arr1d2)):
    print(arr1d2[i1]*arr3d222[i1])

I try to find more efficient way to do this. I suppose that this for loop is the bottleneck of my code.

Attempt:

print(arr1d2[:]*arr3d222[:])

Thanks for any help.

Time Comparision of Answers

import time
import numpy as np
dim=250
arr1d=np.arange(dim)

arr3d,val_arr3=np.zeros([dim,dim,dim]),1
result=np.zeros(np.shape(arr3d))
for i1 in range(len(arr3d)):
  for i2 in range(len(arr3d[0])):
    for i3 in range(len(arr3d[0,0])):
        arr3d[i1,i2,i3]=val_arr3
        val_arr3=val_arr3+1

start_time1 = time.time()
# Correct Solution
for i1 in range(dim):
    result[i1]=arr1d[i1]*arr3d[i1]  
print("Method 1 : For Loop\n%s seconds." % (time.time() - start_time1))

result=np.zeros(np.shape(arr3d))
start_time2 = time.time()
result=arr1d.reshape(len(arr3d),1,1) * arr3d
print("Method 2 : arr1d.reshape(len(arr3d),1,1) * arr3d \n%s seconds." % (time.time() - start_time2))

result=np.zeros(np.shape(arr3d))
start_time3 = time.time()
result=arr1d[:, np.newaxis, np.newaxis] * arr3d
print("Method 3 : arr1d[:, np.newaxis, np.newaxis] * arr3d \n%s seconds." % (time.time() - start_time3))

Result is

Method 1 : For Loop
0.06770634651184082 seconds.
Method 2 : arr1d.reshape(len(arr3d),1,1) * arr3d 
0.05272269248962402 seconds.
Method 3 : arr1d[:, np.newaxis, np.newaxis] * arr3d 
0.048714399337768555 seconds.
3
  • Do you want to do matrix multiplication? Or, do you want the first element of your first array to multiply against each of the first elements of the second array. And second element of first array multiplied against each second element of the lists in second array? Returned as a sum or as the product of the multiplications? Commented Jan 15, 2020 at 18:41
  • I want to multiply first element of 1dArray and whole elements of the first element of 3dArray which is matrix. I mean result[0]=1*[[1,2],[3,4]] and result[1]=2*[[5,6],[7,8]]. It should return 3dArray. Commented Jan 15, 2020 at 18:48
  • 1
    Your correct solution loop doesn't accumulate values; it throws each A away. Commented Jan 15, 2020 at 21:31

2 Answers 2

3

You can use np.newaxis so that the number of dimensions match:

arr1d2[:, np.newaxis, np.newaxis] * arr3d222
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you mikewatt and @emre for editing the answer.
1

Just get the first array to the right shape:

arr1d2.reshape(len(arr3d222),1,1) * arr3d222

4 Comments

Unfortunately, this method is slower than for loop. for Loop : 1.52587890625e-05 seconds. Method 2 : arr1d2.reshape(len(arr3d222),1,1) * arr3d222 2.09808349609375e-05 seconds.
Can you share how to do the comparison? Mine is this: In [193]: %%timeit ...: k = np.empty(0) ...: for i1 in range(len(arr1d2)): ...: k = np.append(k,arr1d2[i1]*arr3d222[i1]) 20.2 µs ± 167 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) In [194]: %timeit arr1d2.reshape(len(arr3d222),1,1) * arr3d222 3.22 µs ± 11.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
By the way, the method 3 does not give the correct result unless it becomes: arr1d2[:, np.newaxis,np.newaxis] * arr3d222
Also, -maybe it is not important- I think your timing calculation for the method 1 is not realistic because A=arr1d[i1]*arr3d[i1] does not give the final result that includes the entire array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.