diff --git a/sklearn/utils/__init__.py b/sklearn/utils/__init__.py index 332e856c641db..4b2665cdd4f77 100644 --- a/sklearn/utils/__init__.py +++ b/sklearn/utils/__init__.py @@ -142,6 +142,8 @@ def safe_indexing(X, indices): not supported. """ if hasattr(X, "iloc"): + # Work-around for indexing with read-only indices in pandas + indices = indices if indices.flags.writeable else indices.copy() # Pandas Dataframes and Series try: return X.iloc[indices] diff --git a/sklearn/utils/tests/test_utils.py b/sklearn/utils/tests/test_utils.py index c0fd079a932fb..fa93bf34fe6bc 100644 --- a/sklearn/utils/tests/test_utils.py +++ b/sklearn/utils/tests/test_utils.py @@ -1,4 +1,4 @@ -from itertools import chain +from itertools import chain, product import warnings import numpy as np @@ -200,10 +200,15 @@ def test_safe_indexing_pandas(): # this happens in joblib memmapping X.setflags(write=False) X_df_readonly = pd.DataFrame(X) - with warnings.catch_warnings(record=True): - X_df_ro_indexed = safe_indexing(X_df_readonly, inds) + inds_readonly = inds.copy() + inds_readonly.setflags(write=False) - assert_array_equal(np.array(X_df_ro_indexed), X_indexed) + for this_df, this_inds in product([X_df, X_df_readonly], + [inds, inds_readonly]): + with warnings.catch_warnings(record=True): + X_df_indexed = safe_indexing(this_df, this_inds) + + assert_array_equal(np.array(X_df_indexed), X_indexed) def test_safe_indexing_mock_pandas():