-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: Add numba engine to several rolling aggregations #38895
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have asv's that exercise both engines? can you show results
@@ -51,6 +51,7 @@ Other enhancements | |||
- :func:`pandas.read_sql_query` now accepts a ``dtype`` argument to cast the columnar data from the SQL database based on user input (:issue:`10285`) | |||
- Improved integer type mapping from pandas to SQLAlchemy when using :meth:`DataFrame.to_sql` (:issue:`35076`) | |||
- :func:`to_numeric` now supports downcasting of nullable ``ExtensionDtype`` objects (:issue:`33013`) | |||
- :meth:`.Rolling.sum`, :meth:`.Expanding.sum`, :meth:`.Rolling.mean`, :meth:`.Expanding.mean`, :meth:`.Rolling.median`, :meth:`.Expanding.median`, :meth:`.Rolling.max`, :meth:`.Expanding.max`, :meth:`.Rolling.min`, and :meth:`.Expanding.min` now support ``Numba`` execution with the ``engine`` keyword (:issue:`38895`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be worth a note in the user docs as well
Here's a simple benchmark
|
) | ||
param_names = ["constructor", "dtype", "function", "engine"] | ||
param_names = ["constructor", "dtype", "function", "engine", "method"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these benchmarks still reasonable in terms of total time, e.g. < 1s per
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each benchmark is around ~1s. Is that too much?
nv.validate_window_func("sum", args, kwargs) | ||
if maybe_use_numba(engine): | ||
if self.method == "table": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be worth a common function for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I inline the args
assignment it would essentially be a 1 line function.
Also I anticipate numba adding an axis
argument incrementally so I would imagine some methods needing the if self.method == "table":
and others not.
pandas/tests/window/test_numba.py
Outdated
engine_kwargs=engine_kwargs, engine="numba" | ||
) | ||
|
||
# Once method='table' is supported, uncomment test below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could just xfail this
pandas/tests/window/test_numba.py
Outdated
engine_kwargs=engine_kwargs, engine="numba" | ||
) | ||
|
||
# Once method='table' is supported, uncomment test below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
thanks as discussed you can write a function like that iterates over the first dimension and calls |
Hi @mroeschke — not sure this is the best forum, but saw this in the release notes and wanted to confirm whether my read of the code was correct. I'm one of the developers of numbagg, and xarray (in which we use numbagg). (And in the olden days, I had occasional pandas contributions.) IIUC, a rolling numba mean in pandas will call Is that correct? Do you have any thoughts on the relative efficiency of that vs. a "rolling algo"; i.e. one that keeps a running sum & count, adding one new value and subtracting one existing value at each step? I had thought that a rolling algo would be significantly faster — particularly for large windows — but I haven't tested it and perhaps you considered this already? IIUC, the cython functions in pandas are rolling algos. And here's an example of that implemented with numba in numbagg: https://github.com/numbagg/numbagg/blob/v0.2.1/numbagg/moving.py#L85 Thanks in advance, and congrats on getting this into pandas! |
You're understanding is correct @max-sixty; this implementation just calls One of the perks about this implementation with numba over the sum and counts method is that the for loop over each window can be parallelized fine with numba which can yield nice performance gains. I don't think that the for looping that tracks sum and counts can be parallelized and yield correct results. Without the parallelism, you're right that tracking sums and counts will be faster than the method I implemented here. I do still need to dig in a little more to see if these assumptions are correct. |
Thanks @mroeschke . And ofc another benefit is that the implementation is much more general, and can take user-jittable functions. I'd be interested to know how benchmarks look if you do run them! |
One other point — though very low confidence — it looks like you had some issues with supplying an |
black pandas
git diff upstream/master -u -- "*.py" | flake8 --diff
Adds
engine
andengine_kwargs
argument tomean
,median
,sum
,min
,max