将一个数组的每个元素乘以另一个数组的每个元素

问题描述 投票:2回答:5

说我有两个数组,

import numpy as np


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

什么是最快的,最Pythonic的等方式来获得一个新数组z,其元素数等于x.size * y.size,其中元素是每对元素(x_i, y_j)的乘积]从两个输入数组。

换句话说,我正在寻找zz[k]的数组x[i] * y[j]

一种简单但效率低下的方法如下:

z = np.empty(x.size * y.size)
counter = 0
for i in x:
    for j in y:
        z[counter] = i * j
        counter += 1

运行上面的代码显示此示例中的z

In [3]: z
Out[3]: 
array([  5.,   6.,   7.,   8.,  10.,  12.,  14.,  16.,  15.,  18.,  21.,
        24.,  20.,  24.,  28.,  32.])
python arrays numpy vectorization cartesian-product
5个回答
2
投票

这里可以建议另外两种方法。

使用matrix-multiplication with np.dot

matrix-multiplication with np.dot

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

np.einsum

运行时测试

np.einsum

np.einsum('i,j->ij',x,y).ravel() 相同,但用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 代替@BilalAkil's answer作为更快的替代方法-

@BilalAkil's answer

ravel()

flatten()

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

@BilalAkil's answer

4
投票

嗯,我对numpy并没有太多的经验,但是通过快速搜索我发现了这一点:@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

编辑:@Divakar的回答告诉我们,拉夫除拉平外会做与拉平相同的操作,所以请改用拉平。

因此,您的情况如下所示:

@Tim Leathart's answer

奖励:您可以用这个去多维!


2
投票

这是一种实现方法:

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

2
投票

这里是一种方法:

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]]) 循环(但至少我要摆脱其中一个循环)。

UPDATE

作为一个班轮,其他提供的答案比这个答案更好(根据我的标准,它重视简洁性)。下面的计时结果显示@BilalAkil的答案比@TimLeathart的答案要快:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flatten.html

0
投票

我知道我在这里参加聚会迟到了,但是我想以后对任何阅读此问题的人都应该戴上帽子。使用与@Divakar相同的度量标准,我在列表中添加了我认为是更直观的解决方案(测得的第一个代码段):

>>> np.multiply.outer(x, y).ravel()

基于执行时间的相似性,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() 的功能似乎与我的内部解决方案完全相同,尽管您应该使用大量盐进行此类观察。

之所以我觉得它更直观,是因为与所有其他解决方案不同,它的语法并不严格限于乘法。例如,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 将为x中的每个a和y中的b提供一个/ b。

© www.soinside.com 2019 - 2024. All rights reserved.