From e2e9ad89b8a3ca7738bf74ec4cdad39ced1483b2 Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 16:19:11 +0100 Subject: [PATCH 1/8] BUG: Error for Series.loc on array of same size (GH37748) added test --- pandas/tests/indexing/test_iloc.py | 11 +++++++++++ pandas/tests/indexing/test_loc.py | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/pandas/tests/indexing/test_iloc.py b/pandas/tests/indexing/test_iloc.py index 554b93c7cab5a..bcf3beb8c9202 100644 --- a/pandas/tests/indexing/test_iloc.py +++ b/pandas/tests/indexing/test_iloc.py @@ -1042,3 +1042,14 @@ def test_iloc_setitem_pure_position_based(self): ser1.iloc[1:3] = ser2.iloc[1:3] expected = Series([1, 5, 6]) tm.assert_series_equal(ser1, expected) + + @pytest.mark.parametrize("size", [0, 4, 5, 6]) + def test_iloc_setitem_with_array(self, size): + # GH37748 + ser = Series(0, index=range(5), dtype="object") + + expected = np.zeros(size) + ser.iloc[0] = expected + result = ser[0] + + tm.assert_numpy_array_equal(result, expected) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index f6aa2371cf13a..425d80f0f4a8a 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2072,3 +2072,14 @@ def test_loc_setitem_dt64tz_values(self): s2["a"] = expected result = s2["a"] assert result == expected + + @pytest.mark.parametrize("size", [0, 4, 5, 6]) + def test_loc_setitem_with_array(self, size): + # GH37748 + ser = Series(0, index=list("abcde"), dtype="object") + + expected = np.zeros(size) + ser.loc["a"] = expected + result = ser[0] + + tm.assert_numpy_array_equal(result, expected) From 482f34936c72a41c6e00b642f345d95960627e1a Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 17:27:01 +0100 Subject: [PATCH 2/8] added tests cases for is_scalar_indexer, ndim=1 --- pandas/tests/indexing/test_indexers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/tests/indexing/test_indexers.py b/pandas/tests/indexing/test_indexers.py index 744f9441e7376..14b2b494d65fb 100644 --- a/pandas/tests/indexing/test_indexers.py +++ b/pandas/tests/indexing/test_indexers.py @@ -28,6 +28,12 @@ def test_is_scalar_indexer(): assert not is_scalar_indexer(slice(None), 1) + indexer = 0 + assert is_scalar_indexer(indexer, 1) + + indexer = (0,) + assert is_scalar_indexer(indexer, 1) + class TestValidateIndices: def test_validate_indices_ok(self): From 92d19609c6db45e608aafaf60607e8832a3f1515 Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 17:28:05 +0100 Subject: [PATCH 3/8] allow non-tuple scalar for ndim=1 in is_scalar_indexer --- pandas/core/indexers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/core/indexers.py b/pandas/core/indexers.py index b6713bc760c5e..da4654bbf2c10 100644 --- a/pandas/core/indexers.py +++ b/pandas/core/indexers.py @@ -79,6 +79,9 @@ def is_scalar_indexer(indexer, ndim: int) -> bool: ------- bool """ + if ndim == 1 and is_integer(indexer): + # GH37748: allow indexer to be an integer for Series + return True if isinstance(indexer, tuple): if len(indexer) == ndim: return all( From f376ec56b24a131ce889dd606ca29fc67c17b465 Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 18:05:56 +0100 Subject: [PATCH 4/8] whatsnew entry --- doc/source/whatsnew/v1.2.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 8dbc6728dccfe..f14605342cbcc 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -677,6 +677,7 @@ Indexing - Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.__getitem__` raising ``KeyError`` when columns were :class:`MultiIndex` with only one level (:issue:`29749`) - Bug in :meth:`Series.__getitem__` and :meth:`DataFrame.__getitem__` raising blank ``KeyError`` without missing keys for :class:`IntervalIndex` (:issue:`27365`) - Bug in setting a new label on a :class:`DataFrame` or :class:`Series` with a :class:`CategoricalIndex` incorrectly raising ``TypeError`` when the new label is not among the index's categories (:issue:`38098`) +- Bug in :meth:`Series.loc` and :meth:`Series.iloc` raising ``ValueError`` when inserting an array in a ``object`` Series of equal length (:issue:`37748`) Missing ^^^^^^^ From 0165b30c9e50e1a97b3f095c1b54302aaf9c972a Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 21:06:12 +0100 Subject: [PATCH 5/8] more testing --- pandas/_testing.py | 12 ++++++++++++ pandas/tests/indexing/test_iloc.py | 11 ----------- pandas/tests/indexing/test_loc.py | 24 +++++++++++++++++++++--- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/pandas/_testing.py b/pandas/_testing.py index 469f5e1bed6ba..d734bac23b078 100644 --- a/pandas/_testing.py +++ b/pandas/_testing.py @@ -1755,6 +1755,18 @@ def assert_equal(left, right, **kwargs): raise NotImplementedError(type(left)) +def assert_python_equal(left, right): + """ + Check left and right are equal w.r.t the ``==`` operator. + + Parameters + ---------- + left : object + right : object + """ + assert left == right + + def box_expected(expected, box_cls, transpose=True): """ Helper function to wrap the expected output of a test in a given box_class. diff --git a/pandas/tests/indexing/test_iloc.py b/pandas/tests/indexing/test_iloc.py index bcf3beb8c9202..554b93c7cab5a 100644 --- a/pandas/tests/indexing/test_iloc.py +++ b/pandas/tests/indexing/test_iloc.py @@ -1042,14 +1042,3 @@ def test_iloc_setitem_pure_position_based(self): ser1.iloc[1:3] = ser2.iloc[1:3] expected = Series([1, 5, 6]) tm.assert_series_equal(ser1, expected) - - @pytest.mark.parametrize("size", [0, 4, 5, 6]) - def test_iloc_setitem_with_array(self, size): - # GH37748 - ser = Series(0, index=range(5), dtype="object") - - expected = np.zeros(size) - ser.iloc[0] = expected - result = ser[0] - - tm.assert_numpy_array_equal(result, expected) diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 425d80f0f4a8a..7bb94d1c583c3 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2073,13 +2073,31 @@ def test_loc_setitem_dt64tz_values(self): result = s2["a"] assert result == expected + @pytest.mark.parametrize( + "array_fn,assert_fn", + [ + (np.zeros, tm.assert_numpy_array_equal), + (pd.array, tm.assert_extension_array_equal), + (list, tm.assert_python_equal), + (tuple, tm.assert_python_equal), + ], + ) @pytest.mark.parametrize("size", [0, 4, 5, 6]) - def test_loc_setitem_with_array(self, size): + def test_loc_iloc_setitem_with_listlike(self, size, array_fn, assert_fn): # GH37748 + # testing insertion, in Series of size N (here 5), of listlike + # of size 0, N-1, N, N+1 + + expected = array_fn([0] * size) + ser = Series(0, index=list("abcde"), dtype="object") - expected = np.zeros(size) ser.loc["a"] = expected result = ser[0] + assert_fn(result, expected) - tm.assert_numpy_array_equal(result, expected) + ser = Series(0, index=list("abcde"), dtype="object") + + ser.iloc[0] = expected + result = ser[0] + assert_fn(result, expected) From 1aa4bedbea128590337c54532dd3c1c9d8be67f7 Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 23:06:37 +0100 Subject: [PATCH 6/8] reworked whatsnew entry --- doc/source/whatsnew/v1.2.0.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index f14605342cbcc..745e9a0f51e65 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -677,7 +677,8 @@ Indexing - Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.__getitem__` raising ``KeyError`` when columns were :class:`MultiIndex` with only one level (:issue:`29749`) - Bug in :meth:`Series.__getitem__` and :meth:`DataFrame.__getitem__` raising blank ``KeyError`` without missing keys for :class:`IntervalIndex` (:issue:`27365`) - Bug in setting a new label on a :class:`DataFrame` or :class:`Series` with a :class:`CategoricalIndex` incorrectly raising ``TypeError`` when the new label is not among the index's categories (:issue:`38098`) -- Bug in :meth:`Series.loc` and :meth:`Series.iloc` raising ``ValueError`` when inserting an array in a ``object`` Series of equal length (:issue:`37748`) +- Bug in :meth:`Series.loc` and :meth:`Series.iloc` raising ``ValueError`` when inserting a listlike ``np.array``, ``list`` or ``tuple`` in an ``object`` Series of equal length (:issue:`37748`) +- Bug in :meth:`Series.loc` and :meth:`Series.iloc` setting all the values of an ``object`` Series with those of a listlike ``ExtensionArray`` instead of inserting it (:issue:`38271`) Missing ^^^^^^^ From ed16223bd169f029a45d6d488fea42b2a0e6deb7 Mon Sep 17 00:00:00 2001 From: lpc Date: Fri, 4 Dec 2020 06:39:36 +0100 Subject: [PATCH 7/8] test with assert_series_equal + fix np.zeros -> np.array --- pandas/_testing.py | 12 ----------- pandas/tests/indexing/test_loc.py | 33 +++++++++++-------------------- 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/pandas/_testing.py b/pandas/_testing.py index d734bac23b078..469f5e1bed6ba 100644 --- a/pandas/_testing.py +++ b/pandas/_testing.py @@ -1755,18 +1755,6 @@ def assert_equal(left, right, **kwargs): raise NotImplementedError(type(left)) -def assert_python_equal(left, right): - """ - Check left and right are equal w.r.t the ``==`` operator. - - Parameters - ---------- - left : object - right : object - """ - assert left == right - - def box_expected(expected, box_cls, transpose=True): """ Helper function to wrap the expected output of a test in a given box_class. diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 7bb94d1c583c3..68f12a939e061 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2073,31 +2073,20 @@ def test_loc_setitem_dt64tz_values(self): result = s2["a"] assert result == expected - @pytest.mark.parametrize( - "array_fn,assert_fn", - [ - (np.zeros, tm.assert_numpy_array_equal), - (pd.array, tm.assert_extension_array_equal), - (list, tm.assert_python_equal), - (tuple, tm.assert_python_equal), - ], - ) + @pytest.mark.parametrize("array_fn", [np.array, pd.array, list, tuple]) @pytest.mark.parametrize("size", [0, 4, 5, 6]) - def test_loc_iloc_setitem_with_listlike(self, size, array_fn, assert_fn): + def test_loc_iloc_setitem_with_listlike(self, size, array_fn): # GH37748 - # testing insertion, in Series of size N (here 5), of listlike + # testing insertion, in a Series of size N (here 5), of a listlike object # of size 0, N-1, N, N+1 - expected = array_fn([0] * size) + arr = array_fn([0] * size) + expected = Series([arr, 0, 0, 0, 0], index=list("abcde"), dtype=object) - ser = Series(0, index=list("abcde"), dtype="object") - - ser.loc["a"] = expected - result = ser[0] - assert_fn(result, expected) - - ser = Series(0, index=list("abcde"), dtype="object") + ser = Series(0, index=list("abcde"), dtype=object) + ser.loc["a"] = arr + tm.assert_series_equal(ser, expected) - ser.iloc[0] = expected - result = ser[0] - assert_fn(result, expected) + ser = Series(0, index=list("abcde"), dtype=object) + ser.iloc[0] = arr + tm.assert_series_equal(ser, expected) From 039a6f990d76842bd071e34f9434e95e1b746376 Mon Sep 17 00:00:00 2001 From: lpc Date: Sat, 5 Dec 2020 01:42:39 +0100 Subject: [PATCH 8/8] cr: add issue to whatsnew --- doc/source/whatsnew/v1.2.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index ab3ca15de9d04..7c78e321a7559 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -677,7 +677,7 @@ Indexing - Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.__getitem__` raising ``KeyError`` when columns were :class:`MultiIndex` with only one level (:issue:`29749`) - Bug in :meth:`Series.__getitem__` and :meth:`DataFrame.__getitem__` raising blank ``KeyError`` without missing keys for :class:`IntervalIndex` (:issue:`27365`) - Bug in setting a new label on a :class:`DataFrame` or :class:`Series` with a :class:`CategoricalIndex` incorrectly raising ``TypeError`` when the new label is not among the index's categories (:issue:`38098`) -- Bug in :meth:`Series.loc` and :meth:`Series.iloc` raising ``ValueError`` when inserting a listlike ``np.array``, ``list`` or ``tuple`` in an ``object`` Series of equal length (:issue:`37748`) +- Bug in :meth:`Series.loc` and :meth:`Series.iloc` raising ``ValueError`` when inserting a listlike ``np.array``, ``list`` or ``tuple`` in an ``object`` Series of equal length (:issue:`37748`, :issue:`37486`) - Bug in :meth:`Series.loc` and :meth:`Series.iloc` setting all the values of an ``object`` Series with those of a listlike ``ExtensionArray`` instead of inserting it (:issue:`38271`) Missing