Home > Net >  Numpy: improve arrays operations
Numpy: improve arrays operations

Time:01-11

As an example, I have the 2 following 1d-arrays:

import numpy as np

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

Now, I need to multiply a for each element of b in order to obtain a 2d-array:

[[5 10 15 20],
 [6 12 18 24]]

Now, I solved the problem by creating 2 new 2d-arrays by repeating either rows or columns and then performing the multiplication, i.e.:

a_2d = np.repeat(a[np.newaxis, :], b.size, axis=0)
b_2d = np.tile(b[:, np.newaxis], a.size)

print(a_2d*b_2d)
#[[ 5 10 15 20]
# [ 6 12 18 24]]

Is there a way to make this operation more efficient?

This would not be limited to multiplications only but, ideally, applicable to all 4 operations. Thanks a lot!

CodePudding user response:

Use broadcasting:

>>> a * b[:, np.newaxis]
array([[ 5, 10, 15, 20],
       [ 6, 12, 18, 24]])
>>> a   b[:, np.newaxis]
array([[ 6,  7,  8,  9],
       [ 7,  8,  9, 10]])

CodePudding user response:

Another method is using the powerful einsum function, e.g.:

np.einsum("i,j->ji", a, b)

See, e.g., here for a great description of the function.

CodePudding user response:

Use numpy.outer

np.outer(b, a)

# [[ 5 10 15 20]
#  [ 6 12 18 24]]

CodePudding user response:

Comparative answers:

For your sample:

# einsum
%timeit np.einsum("i,j->ji", a, b)
2.1 µs ± 34.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

# outer
%timeit np.outer(b, a)
1.94 µs ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

# broadcast
%timeit a * b[:, np.newaxis]
938 ns ± 10.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

For a -> 10000, b -> 500

# einsum
%timeit np.einsum("i,j->ji", a, b)
7.02 ms ± 149 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# outer
%timeit np.outer(b, a)
4.62 ms ± 224 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# broadcast
%timeit a * b[:, np.newaxis]
4.6 ms ± 121 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
  • Related