I'm puzzled by the fact that the function comb
of SciPy appears to be slower than a naive Python implementation. This is the measured time for two equivalent programs solving the Problem 53 of Project Euler.
%%timeit
from scipy.misc import comb
result = 0
for n in range(1, 101):
for k in range(1, n + 1):
if comb(n, k) > 1000000:
result += 1
result
Output:
1 loops, best of 3: 483 ms per loop
%%timeit
from math import factorial
def comb(n, k):
return factorial(n) / factorial(k) / factorial(n - k)
result = 0
for n in range(1, 101):
for k in range(1, n + 1):
if comb(n, k) > 1000000:
result += 1
result
Output:
10 loops, best of 3: 86.9 ms per loop
The second version is about 5 times faster (tested on two Macs, python-2.7.9-1, IPython 2.3.1-py27_0). Is this an expected behaviour of the comb
function of SciPy (source code)? What am I doing wrong?
Edit (SciPy from the Anaconda 3.7.3-py27_0 distribution):
import scipy; print scipy.version.version
0.12.0
Edit (same difference outside IPython):
$ time python with_scipy.py
real 0m0.700s
user 0m0.610s
sys 0m0.069s
$ time python without_scipy.py
real 0m0.134s
user 0m0.099s
sys 0m0.015s
If we select k things from a total of n options and we don't care in what order they are, the total number of combinations (the number of different ways to do this) is: C(n,k)=(nk)=n!k! (n−k)!
Remember, the formula to calculate combinations is nCr = n! / r! * (n - r)!, where n represents the number of items, and r represents the number of items being chosen at a time.
The nPr (permutation) formula is: nPr = n!/(n-r)! The nCr (combination) formula is: nCr = n!/r!(
Python Numbers | choice() functionchoice() is an inbuilt function in Python programming language that returns a random item from a list, tuple, or string. Syntax: random. choice(sequence) Parameters: sequence is a mandatory parameter that can be a list, tuple, or string.
It looks like you may be running the timings incorrectly and measuring the time it takes to load scipy
into memory. When I run:
import timeit
from scipy.misc import comb
from math import factorial
def comb2(n, k):
return factorial(n) / factorial(k) / factorial(n - k)
def test():
result = 0
for n in range(1, 101):
for k in range(1, n + 1):
if comb(n, k) > 1000000:
result += 1
def test2():
result = 0
for n in range(1, 101):
for k in range(1, n + 1):
if comb2(n, k) > 1000000:
result += 1
T = timeit.Timer(test)
print T.repeat(3,50)
T2 = timeit.Timer(test2)
print T2.repeat(3,50)
I get:
[2.2370951175689697, 2.2209839820861816, 2.2142510414123535]
[2.136591911315918, 2.138144016265869, 2.1437559127807617]
which indicates that scipy is slightly faster than the python version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With