You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/source/user_guide/enhancingperf.rst
+59-38
Original file line number
Diff line number
Diff line change
@@ -302,28 +302,63 @@ For more about ``boundscheck`` and ``wraparound``, see the Cython docs on
302
302
303
303
.. _enhancingperf.numba:
304
304
305
-
Using Numba
306
-
-----------
305
+
Numba (JIT compilation)
306
+
-----------------------
307
307
308
-
A recent alternative to statically compiling Cython code, is to use a *dynamic jit-compiler*, Numba.
308
+
An alternative to statically compiling Cython code is to use a dynamic just-in-time (JIT) compiler with `Numba<https://numba.pydata.org/>`__.
309
309
310
-
Numba gives you the power to speed up your applications with high performance functions written directly in Python. With a few annotations, array-oriented and math-heavy Python code can be just-in-time compiled to native machine instructions, similar in performance to C, C++ and Fortran, without having to switch languages or Python interpreters.
310
+
Numba allows you to write a pure Python function which can be JIT compiled to native machine instructions, similar in performance to C, C++ and Fortran,
311
+
by decorating your function with ``@jit``.
311
312
312
-
Numba works by generating optimized machine code using the LLVM compiler infrastructure at import time, runtime, or statically (using the included pycc tool). Numba supports compilation of Python to run on either CPU or GPU hardware, and is designed to integrate with the Python scientific software stack.
313
+
Numba works by generating optimized machine code using the LLVM compiler infrastructure at import time, runtime, or statically (using the included pycc tool).
314
+
Numba supports compilation of Python to run on either CPU or GPU hardware and is designed to integrate with the Python scientific software stack.
313
315
314
316
.. note::
315
317
316
-
You will need to install Numba. This is easy with ``conda``, by using: ``conda install numba``, see :ref:`installing using miniconda<install.miniconda>`.
318
+
The ``@jit`` compilation will add overhead to the runtime of the function, so performance benefits may not be realized especially when using small data sets.
319
+
Consider `caching <https://numba.readthedocs.io/en/stable/developer/caching.html>`__ your function to avoid compilation overhead each time your function is run.
317
320
318
-
.. note::
321
+
Numba can be used in 2 ways with pandas:
322
+
323
+
#. Specify the ``engine="numba"`` keyword in select pandas methods
324
+
#. Define your own Python function decorated with ``@jit`` and pass the underlying NumPy array of :class:`Series` or :class:`Dataframe` (using ``to_numpy()``) into the function
325
+
326
+
pandas Numba Engine
327
+
~~~~~~~~~~~~~~~~~~~
328
+
329
+
If Numba is installed, one can specify ``engine="numba"`` in select pandas methods to execute the method using Numba.
330
+
Methods that support ``engine="numba"`` will also have an ``engine_kwargs`` keyword that accepts a dictionary that allows one to specify
331
+
``"nogil"``, ``"nopython"`` and ``"parallel"`` keys with boolean values to pass into the ``@jit`` decorator.
332
+
If ``engine_kwargs`` is not specified, it defaults to ``{"nogil": False, "nopython": True, "parallel": False}`` unless otherwise specified.
333
+
334
+
In terms of performance, **the first time a function is run using the Numba engine will be slow**
335
+
as Numba will have some function compilation overhead. However, the JIT compiled functions are cached,
336
+
and subsequent calls will be fast. In general, the Numba engine is performant with
337
+
a larger amount of data points (e.g. 1+ million).
319
338
320
-
As of Numba version 0.20, pandas objects cannot be passed directly to Numba-compiled functions. Instead, one must pass the NumPy array underlying the pandas object to the Numba-compiled function as demonstrated below.
339
+
.. code-block:: ipython
340
+
341
+
In [1]: data = pd.Series(range(1_000_000)) # noqa: E225
342
+
343
+
In [2]: roll = data.rolling(10)
321
344
322
-
Jit
323
-
~~~
345
+
In [3]: def f(x):
346
+
...: return np.sum(x) + 5
347
+
# Run the first time, compilation time will affect performance
348
+
In [4]: %timeit -r 1 -n 1 roll.apply(f, engine='numba', raw=True)
349
+
1.23 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
350
+
# Function is cached and performance will improve
351
+
In [5]: %timeit roll.apply(f, engine='numba', raw=True)
352
+
188 ms ± 1.93 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
324
353
325
-
We demonstrate how to use Numba to just-in-time compile our code. We simply
326
-
take the plain Python code from above and annotate with the ``@jit`` decorator.
354
+
In [6]: %timeit roll.apply(f, engine='cython', raw=True)
355
+
3.92 s ± 59 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
356
+
357
+
Custom Function Examples
358
+
~~~~~~~~~~~~~~~~~~~~~~~~
359
+
360
+
A custom Python function decorated with ``@jit`` can be used with pandas objects by passing their NumPy array
361
+
representations with ``to_numpy()``.
327
362
328
363
.. code-block:: python
329
364
@@ -360,8 +395,6 @@ take the plain Python code from above and annotate with the ``@jit`` decorator.
Read more in the `Numba docs <https://numba.pydata.org/>`__.
451
+
Using ``parallel=True`` (e.g. ``@jit(parallel=True)``) may result in a ``SIGABRT`` if the threading layer leads to unsafe
452
+
behavior. You can first `specify a safe threading layer <https://numba.readthedocs.io/en/stable/user/threading-layer.html#selecting-a-threading-layer-for-safe-parallel-execution>`__
453
+
before running a JIT function with ``parallel=True``.
454
+
455
+
Generally if the you encounter a segfault (``SIGSEGV``) while using Numba, please report the issue
456
+
to the `Numba issue tracker. <https://github.com/numba/numba/issues/new/choose>`__
Copy file name to clipboardExpand all lines: doc/source/user_guide/window.rst
+23-49
Original file line number
Diff line number
Diff line change
@@ -262,26 +262,24 @@ and we want to use an expanding window where ``use_expanding`` is ``True`` other
262
262
.. code-block:: ipython
263
263
264
264
In [2]: from pandas.api.indexers import BaseIndexer
265
-
...:
266
-
...: class CustomIndexer(BaseIndexer):
267
-
...:
268
-
...: def get_window_bounds(self, num_values, min_periods, center, closed):
269
-
...: start = np.empty(num_values, dtype=np.int64)
270
-
...: end = np.empty(num_values, dtype=np.int64)
271
-
...: for i in range(num_values):
272
-
...: if self.use_expanding[i]:
273
-
...: start[i] = 0
274
-
...: end[i] = i + 1
275
-
...: else:
276
-
...: start[i] = i
277
-
...: end[i] = i + self.window_size
278
-
...: return start, end
279
-
...:
280
-
281
-
In [3]: indexer = CustomIndexer(window_size=1, use_expanding=use_expanding)
282
-
283
-
In [4]: df.rolling(indexer).sum()
284
-
Out[4]:
265
+
266
+
In [3]: class CustomIndexer(BaseIndexer):
267
+
...: def get_window_bounds(self, num_values, min_periods, center, closed):
268
+
...: start = np.empty(num_values, dtype=np.int64)
269
+
...: end = np.empty(num_values, dtype=np.int64)
270
+
...: for i in range(num_values):
271
+
...: if self.use_expanding[i]:
272
+
...: start[i] = 0
273
+
...: end[i] = i + 1
274
+
...: else:
275
+
...: start[i] = i
276
+
...: end[i] = i + self.window_size
277
+
...: return start, end
278
+
279
+
In [4]: indexer = CustomIndexer(window_size=1, use_expanding=use_expanding)
280
+
281
+
In [5]: df.rolling(indexer).sum()
282
+
Out[5]:
285
283
values
286
284
0 0.0
287
285
1 1.0
@@ -365,45 +363,21 @@ Numba engine
365
363
Additionally, :meth:`~Rolling.apply` can leverage `Numba <https://numba.pydata.org/>`__
366
364
if installed as an optional dependency. The apply aggregation can be executed using Numba by specifying
367
365
``engine='numba'`` and ``engine_kwargs`` arguments (``raw`` must also be set to ``True``).
366
+
See :ref:`enhancing performance with Numba <enhancingperf.numba>` for general usage of the arguments and performance considerations.
367
+
368
368
Numba will be applied in potentially two routines:
369
369
370
370
#. If ``func`` is a standard Python function, the engine will `JIT <https://numba.pydata.org/numba-doc/latest/user/overview.html>`__ the passed function. ``func`` can also be a JITed function in which case the engine will not JIT the function again.
371
371
#. The engine will JIT the for loop where the apply function is applied to each window.
372
372
373
-
.. versionadded:: 1.3.0
374
-
375
-
``mean``, ``median``, ``max``, ``min``, and ``sum`` also support the ``engine`` and ``engine_kwargs`` arguments.
376
-
377
373
The ``engine_kwargs`` argument is a dictionary of keyword arguments that will be passed into the
0 commit comments