How to Multiply Two Arrays Element-Wise

How to perform element-wise multiplication of two lists?

Use a list comprehension mixed with zip():.

[a*b for a,b in zip(lista,listb)]

How to get element-wise matrix multiplication (Hadamard product) in numpy?

For elementwise multiplication of matrix objects, you can use numpy.multiply:

import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
np.multiply(a,b)

Result

array([[ 5, 12],
[21, 32]])

However, you should really use array instead of matrix. matrix objects have all sorts of horrible incompatibilities with regular ndarrays. With ndarrays, you can just use * for elementwise multiplication:

a * b

If you're on Python 3.5+, you don't even lose the ability to perform matrix multiplication with an operator, because @ does matrix multiplication now:

a @ b  # matrix multiplication

Element-wise multiply of multiple numpy 2d arrays

Use stack and prod.

stack will create an array which can be reduced by prod along an axis.

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[2, 2, 2], [3, 3, 3]])
c = np.array([[1, 1, 3], [4, 1, 6]])

unknown_length_list_of_arrays = [a, b, c]

d1 = a * b * c
stacked = np.stack(unknown_length_list_of_arrays)
d2 = np.prod(stacked, axis=0)

np.testing.assert_equal(d1, d2)

How can I do element-wise multiplication of two arrays when one element is derived by a formula?

popul_num = np.array([1.0E5, 0, 0]) # array of molecule numbers for 3 species in model
stoch_rate = np.array([1.0, 0.002, 0.5, 0.04]) # rates of the 4 reactions in the model
evaluate_propensity = np.array((.25,.25,.25,.25)) # An array of the probability of each reaction occuring, is dynamically calculated on each iteration so isn't hard coded.
denominator = np.zeros(4,)

expected_state = np.array([-1.004, 0.002, 0.0])
exptd_state_array = expected_state
b = np.array([[1.0, 0.0, 0.0], [[stoch_rate[1]*(2*(popul_num[0]) - 1)/2], 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.4, 0.0]])

b

array([[1.0, 0.0, 0.0],
[list([199.999]), 0.0, 0.0],
[0.0, 0.5, 0.0],
[0.0, 0.4, 0.0]], dtype=object)

so, b has mixed types. The list is generated by the square brackets around [stoch_rate[1]*(2*(popul_num[0]) - 1)/2]

Multiplication for lists is defined as concatenation with itself: 3 * [5] = [5, 5, 5]. This fails with floats, as @hpaulj pointed out in the comment.

leaving out the square brackets:

b = np.array([[1.0, 0.0, 0.0], [stoch_rate[1]*(2*(popul_num[0]) - 1)/2, 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.4, 0.0]])

b


array([[ 1. , 0. , 0. ],
[199.999, 0. , 0. ],
[ 0. , 0.5 , 0. ],
[ 0. , 0.4 , 0. ]])

Then, the double loop does execute

Multiply 2D NumPy arrays element-wise and sum

You can use np.tensordot -

np.tensordot(A,B, axes=((0,1),(0,1)))

Another way with np.dot after flattening the inputs -

A.ravel().dot(B.ravel())

Another with np.einsum -

np.einsum('ij,ij',A,B)

Sample run -

In [14]: m,n = 4,5

In [15]: A = np.random.rand(m,n)

In [16]: B = np.random.rand(m,n)

In [17]: np.sum(np.multiply(A, B))
Out[17]: 5.1783176986341335

In [18]: np.tensordot(A,B, axes=((0,1),(0,1)))
Out[18]: array(5.1783176986341335)

In [22]: A.ravel().dot(B.ravel())
Out[22]: 5.1783176986341335

In [21]: np.einsum('ij,ij',A,B)
Out[21]: 5.1783176986341326

Runtime test

In [23]: m,n = 5000,5000

In [24]: A = np.random.rand(m,n)
...: B = np.random.rand(m,n)
...:

In [25]: %timeit np.sum(np.multiply(A, B))
...: %timeit np.tensordot(A,B, axes=((0,1),(0,1)))
...: %timeit A.ravel().dot(B.ravel())
...: %timeit np.einsum('ij,ij',A,B)
...:
10 loops, best of 3: 52.2 ms per loop
100 loops, best of 3: 19.5 ms per loop
100 loops, best of 3: 19.5 ms per loop
100 loops, best of 3: 19 ms per loop

Vectorized multiplication: Multiply two vectors in Julia, element-wise

Julia needs a . in front of the operator or function call to indicate you want elementwise multiplication and not an operation on the vector as a unit. This is called broadcasting the array:

 julia> a = [1,2,3]          
3-element Array{Int64,1}:
1
2
3

julia> b = [1,2,3]
3-element Array{Int64,1}:
1
2
3

julia> a .* b
3-element Array{Int64,1}:
1
4
9

Elegant method for element-wise multiplication along shared dimensions of two different-sized arrays?

You can element-wise multiply with arrays of shape (x, y) and (z, x, y).

For example:

a = np.arange(12).reshape((4, 3))
b = np.ones((4, 3, 2))

b[:, :, 0] = 10

x = a * b # :( error

However, if we do

c = np.ones((2, 4, 3))
c[0, :, :] = 10
y = a * c

This works and we get

array([[[  0.,  10.,  20.],
[ 30., 40., 50.],
[ 60., 70., 80.],
[ 90., 100., 110.]],

[[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]]])

Now, to move an axis of an array, you can use the np.moveaxis() function.

b_moved = np.moveaxis(b, -1, 0) # move last axis of b to first position

x = a * b_moved # In the shape of b_moved

y = np.moveaxis(x, 0, -1) # Move first axis of x to the last position

And this gives

x: shape 2x4x3
array([[[ 0., 10., 20.],
[ 30., 40., 50.],
[ 60., 70., 80.],
[ 90., 100., 110.]],

[[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]]])

y: shape 4x3x2
array([[[ 0., 0.],
[ 10., 1.],
[ 20., 2.]],

[[ 30., 3.],
[ 40., 4.],
[ 50., 5.]],

[[ 60., 6.],
[ 70., 7.],
[ 80., 8.]],

[[ 90., 9.],
[100., 10.],
[110., 11.]]])

In summary, you can write a function that does this for you:

def emult3(arr2d, arr3d):
# make sure shapes are compatible
assert (arr2d.ndim, arr3d.ndim) == (2, 3)
assert arr2d.shape == arr3d.shape[0:2]

# do the calculations
x = arr2d * np.moveaxis(arr3d, -1, 0)
return np.moveaxis(x, 0, -1)

Elementwise multiplication of several arrays in Python Numpy

Your fault is in not reading the documentation:

numpy.multiply(x1, x2[, out])

multiply takes exactly two input arrays. The optional third argument is an output array which can be used to store the result. (If it isn't provided, a new array is created and returned.) When you passed three arrays, the third array was overwritten with the product of the first two.



Related Topics



Leave a reply



Submit