Multiplying every element of one array by every element of another array

眉间皱痕 提交于 2020-03-20 06:35:05

问题


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.])

回答1:


Two more approaches could be suggested here.

Using matrix-multiplication with np.dot:

np.dot(x[:,None],y[None]).ravel()

With np.einsum:

np.einsum('i,j->ij',x,y).ravel()

Runtime tests

In [31]: N = 10000
    ...: x = np.random.rand(N)
    ...: y = np.random.rand(N)
    ...: 

In [32]: %timeit np.dot(x[:,None],y[None]).ravel()
1 loops, best of 3: 302 ms per loop

In [33]: %timeit np.einsum('i,j->ij',x,y).ravel()
1 loops, best of 3: 274 ms per loop

Same as @BilalAkil's answer but with ravel() instead of flatten() as a faster alternative -

In [34]: %timeit np.multiply.outer(x, y).ravel() 
1 loops, best of 3: 211 ms per loop

@BilalAkil's answer:

In [35]: %timeit np.multiply.outer(x, y).flatten()
1 loops, best of 3: 451 ms per loop

@Tim Leathart's answer:

In [36]: %timeit np.array([y * a for a in x]).flatten()
1 loops, best of 3: 766 ms per loop



回答2:


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!




回答3:


Here's a way to do it:

import numpy as np

x = np.array([1, 2, 3, 4])
y = np.array([5, 6, 7, 8])
z = np.array([y * a for a in x]).flatten()



回答4:


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).

UPDATE

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


来源:https://stackoverflow.com/questions/30587076/multiplying-every-element-of-one-array-by-every-element-of-another-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!