From 61fad936c1c60e9d6527b16308eb95e55c969023 Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Tue, 28 Mar 2023 21:26:02 +0200 Subject: [PATCH 1/9] Removed unnecessary code --- scripts/validate_docstrings.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/validate_docstrings.py b/scripts/validate_docstrings.py index 487fe44e4d9bc..5c6a5d0e8250f 100755 --- a/scripts/validate_docstrings.py +++ b/scripts/validate_docstrings.py @@ -129,15 +129,14 @@ def get_api_items(api_doc_fd): if line_stripped == "": position = None continue - item = line_stripped.strip() - if item in IGNORE_VALIDATION: + if line_stripped in IGNORE_VALIDATION: continue func = importlib.import_module(current_module) - for part in item.split("."): + for part in line_stripped.split("."): func = getattr(func, part) yield ( - ".".join([current_module, item]), + ".".join([current_module, line_stripped]), func, current_section, current_subsection, From fc7a8d87f154cb447eae271116ed9b9ff661cb83 Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Tue, 28 Mar 2023 22:06:27 +0200 Subject: [PATCH 2/9] Enabled PLW2901 on initial files under pandas/core/* --- pandas/core/apply.py | 20 +++++++++++--------- pandas/core/arrays/period.py | 2 +- pandas/core/computation/eval.py | 4 ++-- pandas/core/computation/pytables.py | 3 +-- pandas/core/dtypes/dtypes.py | 9 ++++++--- pandas/core/generic.py | 4 ++-- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 3d3a7fa6f0f33..68512edfc15ee 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1379,10 +1379,10 @@ def relabel_result( # mean 1.5 # mean 1.5 if reorder_mask: - fun = [ + fun_name = [ com.get_callable_name(f) if not isinstance(f, str) else f for f in fun ] - col_idx_order = Index(s.index).get_indexer(fun) + col_idx_order = Index(s.index).get_indexer(fun_name) s = s[col_idx_order] # assign the new user-provided "named aggregation" as index names, and reindex @@ -1421,14 +1421,16 @@ def _managle_lambda_list(aggfuncs: Sequence[Any]) -> Sequence[Any]: if len(aggfuncs) <= 1: # don't mangle for .agg([lambda x: .]) return aggfuncs - i = 0 + mangled_aggfuncs = [] - for aggfunc in aggfuncs: - if com.get_callable_name(aggfunc) == "": - aggfunc = partial(aggfunc) - aggfunc.__name__ = f"" - i += 1 - mangled_aggfuncs.append(aggfunc) + for idx, aggfunc in enumerate(aggfuncs): + if not com.get_callable_name(aggfunc) == "": + mangled_aggfuncs.append(aggfunc) + continue + + partial_aggfunc = partial(aggfunc) + partial_aggfunc.__name__ = f"" + mangled_aggfuncs.append(partial_aggfunc) return mangled_aggfuncs diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 6557a4b674b4f..762be2b76682b 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -1099,7 +1099,7 @@ def _range_from_fields( freqstr = freq.freqstr year, quarter = _make_field_arrays(year, quarter) for y, q in zip(year, quarter): - y, m = parsing.quarter_to_myear(y, q, freqstr) + _, m = parsing.quarter_to_myear(y, q, freqstr) val = libperiod.period_ordinal(y, m, 1, 1, 1, 1, 0, 0, base) ordinals.append(val) else: diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index d19730a321b36..11593976e35c3 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -320,8 +320,8 @@ def eval( first_expr = True target_modified = False - for expr in exprs: - expr = _convert_expression(expr) + for expr_obj in exprs: + expr = _convert_expression(expr_obj) _check_for_locals(expr, level, parser) # get our (possibly passed-in) scope diff --git a/pandas/core/computation/pytables.py b/pandas/core/computation/pytables.py index 98ed86e8a4dec..5175884bca210 100644 --- a/pandas/core/computation/pytables.py +++ b/pandas/core/computation/pytables.py @@ -568,8 +568,7 @@ def __init__( if isinstance(w, PyTablesExpr): local_dict = w.env.scope else: - w = _validate_where(w) - where[idx] = w + where[idx] = _validate_where(w) _where = " & ".join([f"({w})" for w in com.flatten(where)]) else: # _validate_where ensures we otherwise have a string diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index d302085275757..8e480a92ddb59 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -1267,9 +1267,12 @@ def __from_arrow__( chunks = array.chunks results = [] - for arr in chunks: - if isinstance(arr, pyarrow.ExtensionArray): - arr = arr.storage + for arr_chunk in chunks: + arr = ( + arr_chunk.storage + if isinstance(arr_chunk, pyarrow.ExtensionArray) + else arr_chunk + ) left = np.asarray(arr.field("left"), dtype=self.subtype) right = np.asarray(arr.field("right"), dtype=self.subtype) iarr = IntervalArray.from_arrays(left, right, closed=self.closed) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 72fd7fadd0987..488e740c448f7 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -292,9 +292,9 @@ def _init_mgr( """passed a manager and a axes dict""" for a, axe in axes.items(): if axe is not None: - axe = ensure_index(axe) + axe_w_idx = ensure_index(axe) bm_axis = cls._get_block_manager_axis(a) - mgr = mgr.reindex_axis(axe, axis=bm_axis) + mgr = mgr.reindex_axis(axe_w_idx, axis=bm_axis) # make a copy if explicitly requested if copy: From 7bbbdb5652853a40a3c3da7495fdd777a33bd6e8 Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Wed, 29 Mar 2023 18:47:27 +0200 Subject: [PATCH 3/9] Divided pandas/core/* in pyproject.toml. Included some more fixes. --- pandas/core/indexing.py | 7 +++---- pandas/core/sorting.py | 6 +++--- pandas/core/window/rolling.py | 4 ++-- pyproject.toml | 7 ++++++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 6d5daf5025c49..ecd454c6c4f78 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -2285,12 +2285,11 @@ def _align_frame(self, indexer, df: DataFrame) -> DataFrame: for i, ix in enumerate(indexer): ax = self.obj.axes[i] if is_sequence(ix) or isinstance(ix, slice): - if isinstance(ix, np.ndarray): - ix = ix.ravel() + raveled_ix = ix.ravel() if isinstance(ix, np.ndarray) else ix if idx is None: - idx = ax[ix] + idx = ax[raveled_ix] elif cols is None: - cols = ax[ix] + cols = ax[raveled_ix] else: break else: diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index a9ce262c356db..2f065e13f83c4 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -162,9 +162,9 @@ def maybe_lift(lab, size: int) -> tuple[np.ndarray, int]: lshape = list(shape) if not xnull: for i, (lab, size) in enumerate(zip(labels, shape)): - lab, size = maybe_lift(lab, size) - labels[i] = lab - lshape[i] = size + lab_lifted, size_lifted = maybe_lift(lab, size) + labels[i] = lab_lifted + lshape[i] = size_lifted labels = list(labels) diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index ed0de80e381c3..f6c1f7800b71a 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -483,12 +483,12 @@ def _apply_blockwise( # GH#42736 operate column-wise instead of block-wise # As of 2.0, hfunc will raise for nuisance columns try: - arr = self._prep_values(arr) + arr_np = self._prep_values(arr) except (TypeError, NotImplementedError) as err: raise DataError( f"Cannot aggregate non-numeric type: {arr.dtype}" ) from err - res = homogeneous_func(arr) + res = homogeneous_func(arr_np) res_values.append(res) taker.append(i) diff --git a/pyproject.toml b/pyproject.toml index ac6a4a7b2a61b..61e6279e02751 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -302,7 +302,12 @@ exclude = [ # relative imports allowed for asv_bench "asv_bench/*" = ["TID"] # to be enabled gradually -"pandas/core/*" = ["PLR5501", "PLW2901"] +"pandas/core/*" = ["PLR5501"] +"pandas/core/groupby/*" = ["PLW2901"] +"pandas/core/indexes/*" = ["PLW2901"] +"pandas/core/internals/*" = ["PLW2901"] +"pandas/core/reshape/*" = ["PLW2901"] +"pandas/core/strings/*" = ["PLW2901"] "pandas/io/*" = ["PLW2901"] "pandas/tests/*" = ["B028", "PLW2901"] "pandas/plotting/*" = ["PLW2901"] From 33b6b7f1cfa811d1336017b094476f5e91a1386f Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Tue, 4 Apr 2023 22:56:17 +0200 Subject: [PATCH 4/9] Not sure why but the call to partial removes the .__name__ attribute to aggfunc if just returned. --- pandas/core/apply.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 68512edfc15ee..aefbdeaac1e30 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1428,6 +1428,7 @@ def _managle_lambda_list(aggfuncs: Sequence[Any]) -> Sequence[Any]: mangled_aggfuncs.append(aggfunc) continue + partial_aggfunc = aggfunc partial_aggfunc = partial(aggfunc) partial_aggfunc.__name__ = f"" mangled_aggfuncs.append(partial_aggfunc) From d561fbe66e02512b43c4c9fa599c5c6fe48e41b5 Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Thu, 6 Apr 2023 21:50:13 +0200 Subject: [PATCH 5/9] Ignored type checker and corrected possible induced bug in period.py --- pandas/core/apply.py | 6 +++--- pandas/core/arrays/period.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index f443c0452e703..f33439c0c126c 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1430,13 +1430,13 @@ def _managle_lambda_list(aggfuncs: Sequence[Any]) -> Sequence[Any]: mangled_aggfuncs = [] for idx, aggfunc in enumerate(aggfuncs): - if not com.get_callable_name(aggfunc) == "": + if com.get_callable_name(aggfunc) == "": mangled_aggfuncs.append(aggfunc) continue - partial_aggfunc = aggfunc partial_aggfunc = partial(aggfunc) - partial_aggfunc.__name__ = f"" + # "partial[Any]" has no attribute "__name__" + partial_aggfunc.__name__ = f"" # type: ignore[attr-defined] mangled_aggfuncs.append(partial_aggfunc) return mangled_aggfuncs diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 9b3236389b522..bf7e813689d1a 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -1105,8 +1105,8 @@ def _range_from_fields( freqstr = freq.freqstr year, quarter = _make_field_arrays(year, quarter) for y, q in zip(year, quarter): - _, m = parsing.quarter_to_myear(y, q, freqstr) - val = libperiod.period_ordinal(y, m, 1, 1, 1, 1, 0, 0, base) + y_parsed, m = parsing.quarter_to_myear(y, q, freqstr) + val = libperiod.period_ordinal(y_parsed, m, 1, 1, 1, 1, 0, 0, base) ordinals.append(val) else: freq = to_offset(freq) From 7807b06b3976c3b5974d87c79b3a6050e1110996 Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Thu, 6 Apr 2023 22:17:43 +0200 Subject: [PATCH 6/9] Forgot to add the not in previous commit --- pandas/core/apply.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index f33439c0c126c..3a5916a541f63 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1430,7 +1430,7 @@ def _managle_lambda_list(aggfuncs: Sequence[Any]) -> Sequence[Any]: mangled_aggfuncs = [] for idx, aggfunc in enumerate(aggfuncs): - if com.get_callable_name(aggfunc) == "": + if not com.get_callable_name(aggfunc) == "": mangled_aggfuncs.append(aggfunc) continue From 56ed5aa79e1f8c009ebc56a7b36031e970dfaa91 Mon Sep 17 00:00:00 2001 From: ErdiTk <24619655+ErdiTk@users.noreply.github.com> Date: Tue, 11 Apr 2023 22:29:25 +0200 Subject: [PATCH 7/9] Reverted changes and updated pyproject.toml --- pandas/core/apply.py | 17 +++++++---------- pandas/core/arrays/period.py | 6 ++++-- pandas/core/computation/eval.py | 4 ++-- pandas/core/dtypes/dtypes.py | 9 +++------ pandas/core/generic.py | 4 ++-- pandas/core/indexing.py | 7 ++++--- pandas/core/sorting.py | 4 +--- pandas/core/window/rolling.py | 4 ++-- pyproject.toml | 16 ++++++---------- 9 files changed, 31 insertions(+), 40 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 3a5916a541f63..794c060d8abdb 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1427,17 +1427,14 @@ def _managle_lambda_list(aggfuncs: Sequence[Any]) -> Sequence[Any]: if len(aggfuncs) <= 1: # don't mangle for .agg([lambda x: .]) return aggfuncs - + i = 0 mangled_aggfuncs = [] - for idx, aggfunc in enumerate(aggfuncs): - if not com.get_callable_name(aggfunc) == "": - mangled_aggfuncs.append(aggfunc) - continue - - partial_aggfunc = partial(aggfunc) - # "partial[Any]" has no attribute "__name__" - partial_aggfunc.__name__ = f"" # type: ignore[attr-defined] - mangled_aggfuncs.append(partial_aggfunc) + for aggfunc in aggfuncs: + if com.get_callable_name(aggfunc) == "": + aggfunc = partial(aggfunc) + aggfunc.__name__ = f"" + i += 1 + mangled_aggfuncs.append(aggfunc) return mangled_aggfuncs diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index bf7e813689d1a..7ec7ee01aac6a 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -1105,8 +1105,10 @@ def _range_from_fields( freqstr = freq.freqstr year, quarter = _make_field_arrays(year, quarter) for y, q in zip(year, quarter): - y_parsed, m = parsing.quarter_to_myear(y, q, freqstr) - val = libperiod.period_ordinal(y_parsed, m, 1, 1, 1, 1, 0, 0, base) + calendar_year, calendar_month = parsing.quarter_to_myear(y, q, freqstr) + val = libperiod.period_ordinal( + calendar_year, calendar_month, 1, 1, 1, 1, 0, 0, base + ) ordinals.append(val) else: freq = to_offset(freq) diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index 11593976e35c3..d19730a321b36 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -320,8 +320,8 @@ def eval( first_expr = True target_modified = False - for expr_obj in exprs: - expr = _convert_expression(expr_obj) + for expr in exprs: + expr = _convert_expression(expr) _check_for_locals(expr, level, parser) # get our (possibly passed-in) scope diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index cc7890ac8e509..e28c587f00e3e 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -1260,12 +1260,9 @@ def __from_arrow__( chunks = array.chunks results = [] - for arr_chunk in chunks: - arr = ( - arr_chunk.storage - if isinstance(arr_chunk, pyarrow.ExtensionArray) - else arr_chunk - ) + for arr in chunks: + if isinstance(arr, pyarrow.ExtensionArray): + arr = arr.storage left = np.asarray(arr.field("left"), dtype=self.subtype) right = np.asarray(arr.field("right"), dtype=self.subtype) iarr = IntervalArray.from_arrays(left, right, closed=self.closed) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 6d5586c13ed8d..38bac75bd48b9 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -291,9 +291,9 @@ def _init_mgr( """passed a manager and a axes dict""" for a, axe in axes.items(): if axe is not None: - axe_w_idx = ensure_index(axe) + axe = ensure_index(axe) bm_axis = cls._get_block_manager_axis(a) - mgr = mgr.reindex_axis(axe_w_idx, axis=bm_axis) + mgr = mgr.reindex_axis(axe, axis=bm_axis) # make a copy if explicitly requested if copy: diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index ecd454c6c4f78..6d5daf5025c49 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -2285,11 +2285,12 @@ def _align_frame(self, indexer, df: DataFrame) -> DataFrame: for i, ix in enumerate(indexer): ax = self.obj.axes[i] if is_sequence(ix) or isinstance(ix, slice): - raveled_ix = ix.ravel() if isinstance(ix, np.ndarray) else ix + if isinstance(ix, np.ndarray): + ix = ix.ravel() if idx is None: - idx = ax[raveled_ix] + idx = ax[ix] elif cols is None: - cols = ax[raveled_ix] + cols = ax[ix] else: break else: diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 2f065e13f83c4..b59021205f02e 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -162,9 +162,7 @@ def maybe_lift(lab, size: int) -> tuple[np.ndarray, int]: lshape = list(shape) if not xnull: for i, (lab, size) in enumerate(zip(labels, shape)): - lab_lifted, size_lifted = maybe_lift(lab, size) - labels[i] = lab_lifted - lshape[i] = size_lifted + labels[i], lshape[i] = maybe_lift(lab, size) labels = list(labels) diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index e309eb0b6d79e..630af2b594940 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -483,12 +483,12 @@ def _apply_blockwise( # GH#42736 operate column-wise instead of block-wise # As of 2.0, hfunc will raise for nuisance columns try: - arr_np = self._prep_values(arr) + arr = self._prep_values(arr) except (TypeError, NotImplementedError) as err: raise DataError( f"Cannot aggregate non-numeric type: {arr.dtype}" ) from err - res = homogeneous_func(arr_np) + res = homogeneous_func(arr) res_values.append(res) taker.append(i) diff --git a/pyproject.toml b/pyproject.toml index 61e6279e02751..2308ca93b9178 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -301,19 +301,14 @@ exclude = [ [tool.ruff.per-file-ignores] # relative imports allowed for asv_bench "asv_bench/*" = ["TID"] -# to be enabled gradually -"pandas/core/*" = ["PLR5501"] -"pandas/core/groupby/*" = ["PLW2901"] -"pandas/core/indexes/*" = ["PLW2901"] -"pandas/core/internals/*" = ["PLW2901"] -"pandas/core/reshape/*" = ["PLW2901"] -"pandas/core/strings/*" = ["PLW2901"] -"pandas/io/*" = ["PLW2901"] +# to be enabled gradually (PLW2901 to be moved under keep enabled) +"pandas/core/*" = ["PLR5501", "PLW2901"] "pandas/tests/*" = ["B028", "PLW2901"] -"pandas/plotting/*" = ["PLW2901"] "scripts/*" = ["B028"] -# Keep this one enabled +# Keep those enabled "pandas/_typing.py" = ["TCH"] +"pandas/io/*" = ["PLW2901"] +"pandas/plotting/*" = ["PLW2901"] [tool.pylint.messages_control] max-line-length = 88 @@ -361,6 +356,7 @@ disable = [ "use-implicit-booleaness-not-len", "wrong-import-order", "wrong-import-position", + "redefined-loop-name", # misc "abstract-class-instantiated", From c0f4be533851293a36f27ec84ece92ace1c3278b Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 12 Apr 2023 15:57:35 +0100 Subject: [PATCH 8/9] turn off redefined-loop-variable, minimise diff --- pyproject.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c9a561365d3fa..d5298ed186043 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -266,6 +266,8 @@ ignore = [ "PLR0912", # Too many statements "PLR0915", + # Redefined loop name + "PLW2901", # Global statements are discouraged "PLW0603", # Docstrings should not be included in stubs @@ -301,14 +303,12 @@ exclude = [ [tool.ruff.per-file-ignores] # relative imports allowed for asv_bench "asv_bench/*" = ["TID"] -# to be enabled gradually (PLW2901 to be moved under keep enabled) -"pandas/core/*" = ["PLR5501", "PLW2901"] -"pandas/tests/*" = ["B028", "PLW2901"] +# to be enabled gradually +"pandas/core/*" = ["PLR5501"] +"pandas/tests/*" = ["B028"] "scripts/*" = ["B028"] -# Keep those enabled +# Keep this one enabled "pandas/_typing.py" = ["TCH"] -"pandas/io/*" = ["PLW2901"] -"pandas/plotting/*" = ["PLW2901"] [tool.pylint.messages_control] max-line-length = 88 From 5d3ca8baab1bb671bce0e4d9841def57849cefad Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Wed, 12 Apr 2023 15:59:40 +0100 Subject: [PATCH 9/9] revert fun_name change --- pandas/core/apply.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 64aa2aa48dcd2..274a389791a31 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1423,10 +1423,10 @@ def relabel_result( # mean 1.5 # mean 1.5 if reorder_mask: - fun_name = [ + fun = [ com.get_callable_name(f) if not isinstance(f, str) else f for f in fun ] - col_idx_order = Index(s.index).get_indexer(fun_name) + col_idx_order = Index(s.index).get_indexer(fun) s = s[col_idx_order] # assign the new user-provided "named aggregation" as index names, and reindex