Speed Up Your Numpy and Pandas With Numexpr Package: You Have 2 Free Stories Left This Month
Speed Up Your Numpy and Pandas With Numexpr Package: You Have 2 Free Stories Left This Month
You have 2 free stories left this month. Sign up and get an extra one for free.
Introduction
Numpy and Pandas are probably the two most widely used core Python libraries for
data science (DS) and machine learning (ML)tasks. Needless to say, the speed of
evaluating numerical expressions is critically important for these DS/ML tasks and
these two libraries do not disappoint in that regard.
Under the hood, they use fast and optimized vectorized operations (as much as
possible) to speed up the mathematical operations. Plenty of articles have been
written about how Numpy is much superior (especially when you can vectorize your
calculations) over plain-vanilla Python loops or list-based operations.
towardsdatascience.com
In this article, we show, how using a simple extension librar y, called ‘NumExpr’, one
can improve the speed of the mathematical operations, which the core Numpy and
Pandas yield.
The project is hosted here on Github. It is from the PyData stable, the organization
under NumFocus, which also gave rise to Numpy and Pandas.
As per the source, “NumExpr is a fast numerical expression evaluator for NumPy.
With it, expressions that operate on arrays, are accelerated and use less memor y than
doing the same calculation in Python. In addition, its multi-threaded capabilities can
make use of all your cores — which generally results in substantial performance scaling
compared to NumPy.” (source)
Here is the detailed documentation for the librar y and examples of various use
cases.
Wow! That was magical! All we had to do was to write the familiar a+1 Numpy code
in the form of a symbolic expression "a+1" and pass it on to the ne.evaluate()
Note that we ran the same computation 200 times in a 10-loop test to calculate the
execution time. Now, of course, the exact results are somewhat dependent on
the underlying hardware. You are welcome to evaluate this on your machine and
see what improvement you got.
That is a big improvement in the compute time from 11.7 ms to 2.14 ms, on the
average.
Here is the code. We create a Numpy array of the shape (1000000, 5) and extract
five (1000000,1) vectors from it to use in the rational function. Also note, how the
symbolic expression in the NumExpr method understands ‘sqrt’ natively (we just
write sqrt ).
Whoa! That shows a huge speed boost from 47 ms to ~ 4 ms, on average. In fact,
this is a trend that you will notice that the more complicated the expression
becomes and the more number of arrays it involves, the higher the speed boost
becomes with Numexpr!
We can do the same with NumExpr and speed up the filtering process. Here is an
example where we check whether the Euclidean distance measure involving 4
vectors is greater than a certain threshold.
This kind of filtering operation appears all the time in a data science/machine
learning pipeline, and you can imagine how much compute time can be saved by
strategically replacing Numpy evaluations by NumExpr expressions.
Complex numbers!
We can make the jump from the real to the imaginar y domain pretty easily.
NumExpor works equally well with the complex numbers, which is natively
supported by Python and Numpy. Here is an example, which also illustrates the use
of a transcendental operation like a logarithm.
We show a simple example with the following code, where we construct four
DataFrames with 50000 rows and 100 columns each (filled with uniform random
numbers) and evaluate a nonlinear transformation involving those DataFrames —
in one case with native Pandas expression, and in other case using the pd.eval()
method.
Impact of the DataFrame size
We do a similar analysis of the impact of the size (number of rows, while keeping the
number of columns fixed at 100) of the DataFrame on the speed improvement. The
result is shown below,
A short explanation
Basically, the expression is compiled using Python compile function, variables are
extracted and a parse tree structure is built. This tree is then compiled into a
Bytecode program, which describes the element-wise operation flow using
something called ‘vector registers’ (each 4096 elements wide). The key to speed
enhancement is Numexpr’s ability to handle chunks of elements at a time.
NumExpr evaluation ow, Source: Author made with Google Drawing
It skips the Numpy’s practice of using temporary arrays, which waste memor y
and cannot be even fitted into cache memor y for large arrays.
Also, the virtual machine is written entirely in C which makes it faster than
native Python. It is also multi-threaded allowing faster parallelization of the
operations on suitable hardware.
Supported operators
NumExpr supports a wide array of mathematical operators to be used in the
expression but not conditional operators like if or else . The full list of operators
can be found here.
Threadpool configuration
You can also control the number of threads that you want to spawn for parallel
operations with large arrays by setting the environment variable
NUMEXPR_MAX_THREAD . Currently, the maximum possible number of threads is 64 but
there is no real benefit of going higher than the number of virtual cores available on
the underlying CPU node.
Summary
In this article, we show how to take advantage of the special virtual machine-based
expression evaluation paradigm for speeding up mathematical calculations in
Numpy and Pandas. Although this method may not be applicable for all possible
tasks, a large fraction of data science, data wrangling, and statistical modeling
pipeline can take advantage of this with minimal change in the code.
. . .
A lso, you can check the author’s GitHub repositories for code, ideas, and
resources in machine learning and data science. If you are, like me,
passionate about AI/machine learning/data science, please feel free to add me on
LinkedIn or follow me on Twitter.
317
claps
WR ITTEN BY
T irthajyoti Sarkar Follow
AI, data science, and semiconductor| Ph.D. in EE| AI/ML certi cation (Stanford, MIT) | Data
science author | Speaker | Open-source contributor