Python Numpy项目Euler 1广义优化
我已经开始学习Numpy,我正在寻找写这篇文章的方法。我写了Euler 1的一个推广。它需要一个除数列表和一个数字,例如Euler 1中的[3,5]和1000 在纯python中天真地:Python Numpy项目Euler 1广义优化,python,numpy,optimization,generalization,Python,Numpy,Optimization,Generalization,我已经开始学习Numpy,我正在寻找写这篇文章的方法。我写了Euler 1的一个推广。它需要一个除数列表和一个数字,例如Euler 1中的[3,5]和1000 在纯python中天真地: def subn1(divisors, n): return sum(i for i in range(1,n) if not all(i % d for d in divisors)) 对于范围(2,20),1000000,这大约需要2.5秒 我迄今为止第一次也是最好的尝试如下: def subn2
def subn1(divisors, n):
return sum(i for i in range(1,n) if not all(i % d for d in divisors))
对于范围(2,20),1000000,这大约需要2.5秒
我迄今为止第一次也是最好的尝试如下:
def subn2(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[b])
def subn4(divisors, n):
a = np.arange(np.min(divisors),n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[np.where(b)])
def subn4_(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[np.where(b)])
对于范围(2,20)和1000000,运行时间约为0.45秒
我的第三次尝试是删除foor循环并使用纯numpy,但是它在速度方面损失了一小部分,并且使用了更多内存
def subn3(divisors, n):
nums = np.arange(1,n)
divs = np.array([divisors]).T
return np.sum(nums[np.logical_or.reduce(np.mod(nums, divs) == 0, axis=0)])
对于射程(2,20)和100000,这大约需要0.5秒
有没有一种更快的方法可以用“纯”numpy来编写它,还是foor循环不必回避
注意:我知道您可以通过减少除数列表来优化它,因此无需对此进行评论:)一种具有- 运行时测试和验证-
In [14]: # Inputs
...: n = 1000
...: divisors = range(2,20)
...:
In [15]: print subn1(divisors, n)
...: print subn2(divisors, n)
...: print subn3(divisors, n)
...: print subn_broadcasting(divisors, n)
...:
416056
416056
416056
416056
In [16]: %timeit subn1(divisors, n)
...: %timeit subn2(divisors, n)
...: %timeit subn3(divisors, n)
...: %timeit subn_broadcasting(divisors, n)
...:
1000 loops, best of 3: 1.39 ms per loop
1000 loops, best of 3: 480 µs per loop
1000 loops, best of 3: 434 µs per loop
1000 loops, best of 3: 428 µs per loop
嗯,与
n2
和n3
版本相比,似乎没有多大改进。-
运行时测试和验证-
In [14]: # Inputs
...: n = 1000
...: divisors = range(2,20)
...:
In [15]: print subn1(divisors, n)
...: print subn2(divisors, n)
...: print subn3(divisors, n)
...: print subn_broadcasting(divisors, n)
...:
416056
416056
416056
416056
In [16]: %timeit subn1(divisors, n)
...: %timeit subn2(divisors, n)
...: %timeit subn3(divisors, n)
...: %timeit subn_broadcasting(divisors, n)
...:
1000 loops, best of 3: 1.39 ms per loop
1000 loops, best of 3: 480 µs per loop
1000 loops, best of 3: 434 µs per loop
1000 loops, best of 3: 428 µs per loop
嗯,与n2
和n3
版本相比,似乎没有多大改进。您可以使用,如下所示:
def subn2(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[b])
def subn4(divisors, n):
a = np.arange(np.min(divisors),n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[np.where(b)])
def subn4_(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[np.where(b)])
这些测试,如前所述:
%timeit subn1(divisors, n)
%timeit subn2(divisors, n)
%timeit subn3(divisors, n)
%timeit subn_broadcasting(divisors, n)
%timeit subn4(divisors, n)
%timeit subn4_(divisors, n)
1 loops, best of 3: 596 ms per loop
10 loops, best of 3: 30.1 ms per loop
10 loops, best of 3: 32 ms per loop
10 loops, best of 3: 31.9 ms per loop
10 loops, best of 3: 28.2 ms per loop
10 loops, best of 3: 27.4 ms per loop
您可以这样使用:
def subn2(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[b])
def subn4(divisors, n):
a = np.arange(np.min(divisors),n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[np.where(b)])
def subn4_(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[np.where(b)])
这些测试,如前所述:
%timeit subn1(divisors, n)
%timeit subn2(divisors, n)
%timeit subn3(divisors, n)
%timeit subn_broadcasting(divisors, n)
%timeit subn4(divisors, n)
%timeit subn4_(divisors, n)
1 loops, best of 3: 596 ms per loop
10 loops, best of 3: 30.1 ms per loop
10 loops, best of 3: 32 ms per loop
10 loops, best of 3: 31.9 ms per loop
10 loops, best of 3: 28.2 ms per loop
10 loops, best of 3: 27.4 ms per loop