Why list comprehension is much faster than numpy for multiplying arrays? Why list comprehension is much faster than numpy for multiplying arrays? numpy numpy

Why list comprehension is much faster than numpy for multiplying arrays?


Creation of numpy arrays is much slower than creation of lists:

In [153]: %timeit a = [[2,3,5],[3,6,2],[1,3,2]]1000000 loops, best of 3: 308 ns per loopIn [154]: %timeit a = np.array([[2,3,5],[3,6,2],[1,3,2]])100000 loops, best of 3: 2.27 µs per loop

There can also fixed costs incurred by NumPy function calls before the meatof the calculation can be performed by a fast underlying C/Fortran function. This can include ensuring the inputs are NumPy arrays,

These setup/fixed costs are something to keep in mind before assuming NumPysolutions are inherently faster than pure-Python solutions. NumPy shines whenyou set up large arrays once and then perform many fast NumPy operationson the arrays. It may fail to outperform pure Python if the arrays are smallbecause the setup cost can outweigh the benefit of offloading the calculationsto compiled C/Fortran functions. For small arrays there simply may not be enoughcalculations to make it worth it.


If you increase the size of the arrays a bit, and move creation of the arraysinto the setup, then NumPy can be much faster than pure Python:

import numpy as npfrom timeit import timeitN, M = 300, 300a = np.random.randint(100, size=(N,M))b = np.random.randint(100, size=(N,))a2 = a.tolist()b2 = b.tolist()s1="""[[m*n for n in second] for m, second in zip(b2,a2)]"""s2 = """(a.T*b).T"""s3 = """a*b[:,None]"""assert np.allclose([[m*n for n in second] for m, second in zip(b2,a2)], (a.T*b).T)assert np.allclose([[m*n for n in second] for m, second in zip(b2,a2)], a*b[:,None])print 's1: {:.4f}'.format(    timeit(stmt=s1, number=10**3, setup='from __main__ import a2,b2'))print 's2: {:.4f}'.format(    timeit(stmt=s2, number=10**3, setup='from __main__ import a,b'))print 's3: {:.4f}'.format(    timeit(stmt=s3, number=10**3, setup='from __main__ import a,b'))

yields

s1: 4.6990s2: 0.1224s3: 0.1234