玩弄这个并找到inner1d
最快的。然而,该功能是内部的,因此更强大的方法是使用
numpy.einsum("ij,ij->i", a, b)
更好的是对齐你的记忆,使总和发生在第一维,例如,
a = numpy.random.rand(3, n)
b = numpy.random.rand(3, n)
numpy.einsum("ij,ij->j", a, b)
对于10 ** 3 <= n <= 10 ** 6
,这是最快的方法,速度是未转置等效方法的两倍。最大值出现在二级缓存被最大化时,大约为2 * 10 ** 4
.
还要注意,转置后的转换sum
比其未转置的等价物快得多。
该情节是用perfplot创建的(我的一个小项目)
import numpy
from numpy.core.umath_tests import inner1d
import perfplot
def setup(n):
a = numpy.random.rand(n, 3)
b = numpy.random.rand(n, 3)
aT = numpy.ascontiguousarray(a.T)
bT = numpy.ascontiguousarray(b.T)
return (a, b), (aT, bT)
b = perfplot.bench(
setup=setup,
n_range=[2 ** k for k in range(1, 25)],
kernels=[
lambda data: numpy.sum(data[0][0] * data[0][1], axis=1),
lambda data: numpy.einsum("ij, ij->i", data[0][0], data[0][1]),
lambda data: numpy.sum(data[1][0] * data[1][1], axis=0),
lambda data: numpy.einsum("ij, ij->j", data[1][0], data[1][1]),
lambda data: inner1d(data[0][0], data[0][1]),
],
labels=["sum", "einsum", "sum.T", "einsum.T", "inner1d"],
xlabel="len(a), len(b)",
)
b.save("out1.png")
b.save("out2.png", relative_to=3)