Python/Numpy中的线性组合

5 投票
2 回答
13296 浏览
提问于 2025-04-15 23:20

大家好,

我不确定这个问题是不是很傻。

假设我有三个numpy数组,分别是A1、A2和A3,还有三个浮点数c1、c2和c3。

我想计算B = A1*c1 + A2*c2 + A3*c3。

那么numpy会像这样计算吗,

 E1 = A1*c1
 E2 = A2*c2
 E3 = A3*c3
 D1 = E1+E2
 B = D1+E3

还是说它更聪明一些?在C++中,我有一种很好的方法来处理这种操作。

我定义了一系列通用的“LC”模板函数,LC代表线性组合,比如:

template<class T,class D>
void LC( T & R,
    T & L0,D C0,
    T & L1,D C1,
    T & L2,D C2)
{
    R = L0*C0
        +L1*C1
        +L2*C2;        
}

然后我为不同类型进行了专门化,

所以例如,对于一个数组,代码看起来像这样:

for (int i=0; i<L0.length; i++)
    R.array[i] =
    L0.array[i]*C0 +
    L1.array[i]*C1 +
    L2.array[i]*C2;

这样就避免了创建新的中间数组。

这可能看起来有点乱,但效果真的很好。

我可以在python中做类似的事情,但我不确定是否有必要。

提前感谢任何见解。

-nick

2 个回答

3

这段话讲的是 numexpr 这个工具(一个快速的数值数组表达式计算器,适用于Python和NumPy)。在你自己编写代码之前,可以先试试这个工具。

7

虽然理论上 numpy 随时都可以升级它的内部结构来进行各种优化,但目前它并没有这样做:比如说 B = A1*c1 + A2*c2 + A3*c3 这个操作会生成一些临时数组,然后又把它们丢掉(这会占用一些额外的内存,当然,仅此而已)。

而如果你先写 B = A1 * c1,然后再写 B += A2 * c2; B += A3 * c3,在现在的情况下,这样做就能避免使用一些临时内存。

当然,只有在你使用的环境内存比较紧张时,你才能感受到这种差别(因为有些额外的内存只是虚拟的,可能会导致页面错误),而且在处理足够大的数组时,这种情况才会发生,可能会“花掉”所有的真实内存。 在这种极端情况下,稍微调整一下代码确实可以提高性能。

撰写回答