Say I have two arrays,
import numpy as np
x = np.array([1, 2, 3, 4])
y = np.array([5, 6, 7, 8])
What's the fastest, most Pythonic, etc., etc. way to get a new array, z
, with a number of elements equal to x.size * y.size
, in which the elements are the products of every pair of elements (x_i, y_j)
from the two input arrays.
To rephrase, I'm looking for an array z
in which z[k]
is x[i] * y[j]
.
A simple but inefficient way to get this is as follows:
z = np.empty(x.size * y.size)
counter = 0
for i in x:
for j in y:
z[counter] = i * j
counter += 1
Running the above code shows that z
in this example is
In [3]: z
Out[3]:
array([ 5., 6., 7., 8., 10., 12., 14., 16., 15., 18., 21.,
24., 20., 24., 28., 32.])
Here's one way to do it:
import itertools
z = np.empty(x.size * y.size)
counter = 0
for i, j in itertools.product(x, y):
z[counter] = i * j
counter += 1
It'd be nice to get rid of that counter, though, as well as the for
loop (but at least I got rid of one of the loops).
Being one-liners, the other provided answers are better than this one (according to my standards, which value brevity). The timing results below show that @BilalAkil's answer is faster than @TimLeathart's:
In [10]: %timeit np.array([x * j for j in y]).flatten()
The slowest run took 4.37 times longer than the fastest. This could mean that an intermediate result is being cached
10000 loops, best of 3: 24.2 µs per loop
In [11]: %timeit np.multiply.outer(x, y).flatten()
The slowest run took 5.59 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 10.5 µs per loop
Well I haven't much experience with numpy, but a quick search gave me this: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.outer.html
>>> np.multiply.outer([1, 2, 3], [4, 5, 6])
array([[ 4, 5, 6],
[ 8, 10, 12],
[12, 15, 18]])
You can then flatten that array to get the same output as you requested: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flatten.html
EDIT: @Divakar's answer showed us that ravel will do the same thing as flatten, except faster o.O So use that instead.
So in your case, it'd look like this:
>>> np.multiply.outer(x, y).ravel()
BONUS: You can go multi-dimensional with this!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With