使用NumPy数组的列表推导 - 是不好的做法吗?

7
我想知道下面的方法是否被认为是不好的实践,如果是,请给出其他方法的指导。
以下是相关的代码:
a = np.array([[1,2,3],[4,5,6]])
b = np.array([-5,5])
c = np.array([np.multiply(a[x],b[x]) for x in range(2)])

这里的目标是获得一个与'a'相同形状的数组,其中'a'的第一个元素的值乘以'b'的第一个元素,第二个元素的值乘以'b'的第二个元素。 上面的代码可以运行,但由于涉及到列表/数组的混合使用,我担心这不被建议使用 - 但我对更优雅的解决方案不清楚。非常感谢您的帮助!
1个回答

12
NumPythonic 的方式是通过使用 np.newaxis/Noneb 的维度扩展为2D数组,然后让 broadcasting 来进行矢量化的逐元素乘法。 实现如下所示-
c = a * b[:,None]

如果扩展了维度,您也可以使用np.multiply来实现相同的效果,如下所示-

c = np.multiply(a,b[:,None])

最重要的是,以下是一些性能数据,可以说服您使用广播(broadcasting) -

In [176]: a = np.random.rand(2000,3000)

In [177]: b = np.random.rand(2000)

In [178]: %timeit np.array([np.multiply(a[x],b[x]) for x in range(a.shape[0])])
10 loops, best of 3: 118 ms per loop

In [179]: %timeit a * b[:,None]
10 loops, best of 3: 63.8 ms per loop

In [180]: %timeit np.multiply(a,b[:,None])
10 loops, best of 3: 64 ms per loop

那非常有帮助,谢谢!我得更好地理解“newaxis”的概念。 b[:None].shape 仍然会指示一个1维数组而不是2维,所以我不一定指望这个能够起作用... - laszlopanaflex
3
b[:None]b[:, None] 非常不同,逗号是关键。前者是一个切片的一部分,即 slice(None,None,None)。而后者被 NumPy 理解为具有特殊的 newaxis 意义。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接