diff options
| author | Nicolas Graves <ngraves@ngraves.fr> | 2026-08-03 19:24:29 +0200 |
|---|---|---|
| committer | Sharlatan Hellseher <sharlatanus@gmail.com> | 2026-08-08 23:02:28 +0100 |
| commit | 277abc66cff6ea9c076df9142321fe5a32a72b56 (patch) | |
| tree | 785784498a2200da19c3b7187edd0a0a6a5270b1 | |
| parent | ed8af88ee63f91756a14af866ce2ed39eb3c3e62 (diff) | |
gnu: python-pandarallel: Fix build.
* gnu/packages/patches/python-pandarallel-fix-df-applymap.patch: Add
patch.
* gnu/packages/patches/python-pandarallel-fix-parallel_apply.patch:
Likewise.
* gnu/local.mk (dist_patch_DATA): Record patches.
* gnu/packages/python-science.scm (python-pandarallel)
[source]{patches}: Record them.
Signed-off-by: Andreas Enge <andreas@enge.fr>
| -rw-r--r-- | gnu/local.mk | 2 | ||||
| -rw-r--r-- | gnu/packages/patches/python-pandarallel-fix-df-applymap.patch | 48 | ||||
| -rw-r--r-- | gnu/packages/patches/python-pandarallel-fix-parallel_apply.patch | 79 | ||||
| -rw-r--r-- | gnu/packages/python-science.scm | 5 |
4 files changed, 133 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk index f227c550e3a..f78ab43ca1a 100644 --- a/gnu/local.mk +++ b/gnu/local.mk | |||
| @@ -2300,6 +2300,8 @@ dist_patch_DATA = \ | |||
| 2300 | %D%/packages/patches/python-mslice-matplotlib-3.6-compatibility.patch \ | 2300 | %D%/packages/patches/python-mslice-matplotlib-3.6-compatibility.patch \ |
| 2301 | %D%/packages/patches/python-packaging-test-arch.patch \ | 2301 | %D%/packages/patches/python-packaging-test-arch.patch \ |
| 2302 | %D%/packages/patches/python-pandas-2-no-pytz_datetime.patch \ | 2302 | %D%/packages/patches/python-pandas-2-no-pytz_datetime.patch \ |
| 2303 | %D%/packages/patches/python-pandarallel-fix-df-applymap.patch \ | ||
| 2304 | %D%/packages/patches/python-pandarallel-fix-parallel_apply.patch \ | ||
| 2303 | %D%/packages/patches/python-property-cached-asyncio-3_11.patch \ | 2305 | %D%/packages/patches/python-property-cached-asyncio-3_11.patch \ |
| 2304 | %D%/packages/patches/python-pyan3-fix-absolute-path-bug.patch \ | 2306 | %D%/packages/patches/python-pyan3-fix-absolute-path-bug.patch \ |
| 2305 | %D%/packages/patches/python-pyan3-fix-positional-arguments.patch \ | 2307 | %D%/packages/patches/python-pyan3-fix-positional-arguments.patch \ |
diff --git a/gnu/packages/patches/python-pandarallel-fix-df-applymap.patch b/gnu/packages/patches/python-pandarallel-fix-df-applymap.patch new file mode 100644 index 00000000000..8aef98a03fc --- /dev/null +++ b/gnu/packages/patches/python-pandarallel-fix-df-applymap.patch | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | From f4e59d5a12d10b87d55f91e195ec4b8064fa66ca Mon Sep 17 00:00:00 2001 | ||
| 2 | From: goosfrabba <16498111+goosfrabba@users.noreply.github.com> | ||
| 3 | Date: Mon, 6 Jul 2026 10:58:21 -0700 | ||
| 4 | Subject: [PATCH] Fix DataFrame.applymap deprecation on pandas >= 2.1 without | ||
| 5 | dropping pandas < 2.1 | ||
| 6 | |||
| 7 | pandas >= 2.1 deprecates DataFrame.applymap in favour of DataFrame.map, so parallel_applymap | ||
| 8 | raises a FutureWarning (#258). ApplyMap.work now uses DataFrame.map when the installed pandas | ||
| 9 | provides it and falls back to applymap otherwise, fixing the deprecation without dropping | ||
| 10 | pandas < 2.1 or bumping the minimum Python version (the concern raised on #259). The reference | ||
| 11 | computation in test_dataframe_applymap uses the same capability check so it stays warning-free. | ||
| 12 | --- | ||
| 13 | pandarallel/data_types/dataframe.py | 6 ++++++ | ||
| 14 | tests/test_pandarallel.py | 4 +++- | ||
| 15 | 2 files changed, 9 insertions(+), 1 deletion(-) | ||
| 16 | |||
| 17 | diff --git a/pandarallel/data_types/dataframe.py b/pandarallel/data_types/dataframe.py | ||
| 18 | index 29c7e50..e1bc627 100644 | ||
| 19 | --- a/pandarallel/data_types/dataframe.py | ||
| 20 | +++ b/pandarallel/data_types/dataframe.py | ||
| 21 | @@ -66,6 +66,12 @@ def work( | ||
| 22 | user_defined_function_kwargs: Dict[str, Any], | ||
| 23 | extra: Dict[str, Any], | ||
| 24 | ) -> pd.DataFrame: | ||
| 25 | + # pandas >= 2.1 deprecates DataFrame.applymap in favour of DataFrame.map (added in 2.1); | ||
| 26 | + # older pandas only has applymap. Use whichever this pandas provides, so elementwise | ||
| 27 | + # apply keeps working and no longer raises the FutureWarning reported in #258, without | ||
| 28 | + # dropping support for pandas < 2.1. | ||
| 29 | + if hasattr(data, "map"): | ||
| 30 | + return data.map(user_defined_function) | ||
| 31 | return data.applymap(user_defined_function) | ||
| 32 | |||
| 33 | @staticmethod | ||
| 34 | diff --git a/tests/test_pandarallel.py b/tests/test_pandarallel.py | ||
| 35 | index 0f91c32..567c7d5 100644 | ||
| 36 | --- a/tests/test_pandarallel.py | ||
| 37 | +++ b/tests/test_pandarallel.py | ||
| 38 | @@ -232,7 +232,9 @@ def test_dataframe_applymap(pandarallel_init, func_dataframe_applymap, df_size): | ||
| 39 | ) | ||
| 40 | df.index = [item / 10 for item in df.index] | ||
| 41 | |||
| 42 | - res = df.applymap(func_dataframe_applymap) | ||
| 43 | + # pandas >= 2.1 renamed DataFrame.applymap to DataFrame.map; use whichever this pandas | ||
| 44 | + # provides so the reference computation stays warning-free across versions. | ||
| 45 | + res = (df.map if hasattr(df, "map") else df.applymap)(func_dataframe_applymap) | ||
| 46 | res_parallel = df.parallel_applymap(func_dataframe_applymap) | ||
| 47 | assert res.equals(res_parallel) | ||
| 48 | |||
diff --git a/gnu/packages/patches/python-pandarallel-fix-parallel_apply.patch b/gnu/packages/patches/python-pandarallel-fix-parallel_apply.patch new file mode 100644 index 00000000000..2d58cbf6482 --- /dev/null +++ b/gnu/packages/patches/python-pandarallel-fix-parallel_apply.patch | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | From cebc07fed0707457487656836e627a154416d252 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Palash Lalwani <palashlalwani.r@gmail.com> | ||
| 3 | Date: Wed, 22 Jul 2026 21:24:52 +0530 | ||
| 4 | Subject: [PATCH] fix: don't pass grouping columns to | ||
| 5 | groupby().parallel_apply() on pandas >= 3.0 | ||
| 6 | |||
| 7 | Since pandas 3.0, DataFrameGroupBy.apply operates on _obj_with_exclusions, so the | ||
| 8 | grouping columns are no longer passed to the applied function. Iterating a | ||
| 9 | DataFrameGroupBy still yields them, which is how pandarallel builds its chunks, so | ||
| 10 | parallel_apply kept passing them. | ||
| 11 | |||
| 12 | This produced a silent divergence rather than an error: user functions that iterate | ||
| 13 | columns or aggregate across the frame got different results from parallel_apply than | ||
| 14 | from apply. | ||
| 15 | |||
| 16 | Restrict each group to the columns apply would have used, gated on the pandas version | ||
| 17 | so behaviour on pandas < 3.0 is unchanged. | ||
| 18 | |||
| 19 | The groupby test fixture read df.b, but the test also covers groupby(["a", "b"]) where | ||
| 20 | b is now a grouping column, making the reference apply() call raise on pandas 3.0. | ||
| 21 | Switched the fixture to column c, which is never a grouping column in these tests. | ||
| 22 | --- | ||
| 23 | pandarallel/data_types/dataframe_groupby.py | 18 +++++++++++++++++- | ||
| 24 | tests/test_pandarallel.py | 8 ++++++-- | ||
| 25 | 2 files changed, 23 insertions(+), 3 deletions(-) | ||
| 26 | |||
| 27 | diff --git a/pandarallel/data_types/dataframe_groupby.py b/pandarallel/data_types/dataframe_groupby.py | ||
| 28 | index f2dbb91..9b448d7 100644 | ||
| 29 | --- a/pandarallel/data_types/dataframe_groupby.py | ||
| 30 | +++ b/pandarallel/data_types/dataframe_groupby.py | ||
| 31 | @@ -17,8 +17,24 @@ def get_chunks( | ||
| 32 | chunks = chunk(dataframe_groupby.ngroups, nb_workers) | ||
| 33 | iterator = iter(dataframe_groupby) | ||
| 34 | |||
| 35 | + # Since pandas 3.0, `DataFrameGroupBy.apply` operates on | ||
| 36 | + # `_obj_with_exclusions`, i.e. the grouping columns are no longer passed to | ||
| 37 | + # the applied function. Iterating a `DataFrameGroupBy` still yields them | ||
| 38 | + # though, so restrict each group to the columns `apply` would have used. | ||
| 39 | + # On pandas < 3.0 the grouping columns are still passed, so keep them. | ||
| 40 | + columns = ( | ||
| 41 | + dataframe_groupby._obj_with_exclusions.columns | ||
| 42 | + if get_pandas_version() >= (3, 0) | ||
| 43 | + else None | ||
| 44 | + ) | ||
| 45 | + | ||
| 46 | for chunk_ in chunks: | ||
| 47 | - yield [next(iterator) for _ in range(chunk_.stop - chunk_.start)] | ||
| 48 | + groups = [next(iterator) for _ in range(chunk_.stop - chunk_.start)] | ||
| 49 | + | ||
| 50 | + if columns is not None: | ||
| 51 | + groups = [(key, df[columns]) for key, df in groups] | ||
| 52 | + | ||
| 53 | + yield groups | ||
| 54 | |||
| 55 | @staticmethod | ||
| 56 | def work( | ||
| 57 | diff --git a/tests/test_pandarallel.py b/tests/test_pandarallel.py | ||
| 58 | index 0f91c32..2f43458 100644 | ||
| 59 | --- a/tests/test_pandarallel.py | ||
| 60 | +++ b/tests/test_pandarallel.py | ||
| 61 | @@ -93,12 +93,16 @@ def func(x): | ||
| 62 | |||
| 63 | @pytest.fixture() | ||
| 64 | def func_dataframe_groupby_apply(): | ||
| 65 | + # Uses column `c`, which is never a grouping column in the tests below. Since pandas | ||
| 66 | + # 3.0 the grouping columns are not passed to the applied function, so a function | ||
| 67 | + # reading `df.b` would fail on the `groupby(["a", "b"])` case before `parallel_apply` | ||
| 68 | + # is even reached. | ||
| 69 | def func(df): | ||
| 70 | dum = 0 | ||
| 71 | - for item in df.b: | ||
| 72 | + for item in df.c: | ||
| 73 | dum += math.log10(math.sqrt(math.exp(item**2))) | ||
| 74 | |||
| 75 | - return dum / len(df.b) | ||
| 76 | + return dum / len(df.c) | ||
| 77 | |||
| 78 | return func | ||
| 79 | |||
diff --git a/gnu/packages/python-science.scm b/gnu/packages/python-science.scm index 9389d849c11..0ab894aecbf 100644 --- a/gnu/packages/python-science.scm +++ b/gnu/packages/python-science.scm | |||
| @@ -4649,7 +4649,10 @@ convention of suggesting best recommended practices for using | |||
| 4649 | (commit (string-append "v" version)))) | 4649 | (commit (string-append "v" version)))) |
| 4650 | (file-name (git-file-name name version)) | 4650 | (file-name (git-file-name name version)) |
| 4651 | (sha256 | 4651 | (sha256 |
| 4652 | (base32 "0r2wlxlwp4wia0vm15k4cp421mwa20k4k5g2ml01inprj8bl1p0p")))) | 4652 | (base32 "0r2wlxlwp4wia0vm15k4cp421mwa20k4k5g2ml01inprj8bl1p0p")) |
| 4653 | (patches | ||
| 4654 | (search-patches "python-pandarallel-fix-df-applymap.patch" | ||
| 4655 | "python-pandarallel-fix-parallel_apply.patch")))) | ||
| 4653 | (build-system pyproject-build-system) | 4656 | (build-system pyproject-build-system) |
| 4654 | (arguments | 4657 | (arguments |
| 4655 | (list | 4658 | (list |
