Skip to content

Commit b7e7fd3

Browse files
margaretjreback
authored andcommitted
BUG: .iloc[:] and .loc[:] return a copy of the original object #13873 (#16443)
closes #13873
1 parent a43dcf9 commit b7e7fd3

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Conversion
9797
Indexing
9898
^^^^^^^^
9999

100+
- When called with a null slice (e.g. ``df.iloc[:]``), the``iloc`` and ``loc`` indexers return a shallow copy of the original object. Previously they returned the original object. (:issue:`13873`).
100101

101102

102103
I/O

pandas/core/indexing.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,10 @@ def _getitem_lowerdim(self, tup):
988988
if len(new_key) == 1:
989989
new_key, = new_key
990990

991+
# Slices should return views, but calling iloc/loc with a null
992+
# slice returns a new object.
993+
if is_null_slice(new_key):
994+
return section
991995
# This is an elided recursive call to iloc/loc/etc'
992996
return getattr(section, self.name)[new_key]
993997

@@ -1250,7 +1254,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
12501254
obj = self.obj
12511255

12521256
if not need_slice(slice_obj):
1253-
return obj
1257+
return obj.copy(deep=False)
12541258
indexer = self._convert_slice_indexer(slice_obj, axis)
12551259

12561260
if isinstance(indexer, slice):
@@ -1349,7 +1353,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
13491353
""" this is pretty simple as we just have to deal with labels """
13501354
obj = self.obj
13511355
if not need_slice(slice_obj):
1352-
return obj
1356+
return obj.copy(deep=False)
13531357

13541358
labels = obj._get_axis(axis)
13551359
indexer = labels.slice_indexer(slice_obj.start, slice_obj.stop,
@@ -1690,7 +1694,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
16901694
obj = self.obj
16911695

16921696
if not need_slice(slice_obj):
1693-
return obj
1697+
return obj.copy(deep=False)
16941698

16951699
slice_obj = self._convert_slice_indexer(slice_obj, axis)
16961700
if isinstance(slice_obj, slice):

pandas/tests/indexing/test_iloc.py

+18
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,21 @@ def test_iloc_empty_list_indexer_is_ok(self):
591591
tm.assert_frame_equal(df.iloc[[]], df.iloc[:0, :],
592592
check_index_type=True,
593593
check_column_type=True)
594+
595+
def test_identity_slice_returns_new_object(self):
596+
# GH13873
597+
original_df = DataFrame({'a': [1, 2, 3]})
598+
sliced_df = original_df.iloc[:]
599+
assert sliced_df is not original_df
600+
601+
# should be a shallow copy
602+
original_df['a'] = [4, 4, 4]
603+
assert (sliced_df['a'] == 4).all()
604+
605+
original_series = Series([1, 2, 3, 4, 5, 6])
606+
sliced_series = original_series.iloc[:]
607+
assert sliced_series is not original_series
608+
609+
# should also be a shallow copy
610+
original_series[:3] = [7, 8, 9]
611+
assert all(sliced_series[:3] == [7, 8, 9])

pandas/tests/indexing/test_loc.py

+25
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,28 @@ def test_loc_empty_list_indexer_is_ok(self):
630630
tm.assert_frame_equal(df.loc[[]], df.iloc[:0, :],
631631
check_index_type=True,
632632
check_column_type=True)
633+
634+
def test_identity_slice_returns_new_object(self):
635+
# GH13873
636+
original_df = DataFrame({'a': [1, 2, 3]})
637+
sliced_df = original_df.loc[:]
638+
assert sliced_df is not original_df
639+
assert original_df[:] is not original_df
640+
641+
# should be a shallow copy
642+
original_df['a'] = [4, 4, 4]
643+
assert (sliced_df['a'] == 4).all()
644+
645+
# These should not return copies
646+
assert original_df is original_df.loc[:, :]
647+
df = DataFrame(np.random.randn(10, 4))
648+
assert df[0] is df.loc[:, 0]
649+
650+
# Same tests for Series
651+
original_series = Series([1, 2, 3, 4, 5, 6])
652+
sliced_series = original_series.loc[:]
653+
assert sliced_series is not original_series
654+
assert original_series[:] is not original_series
655+
656+
original_series[:3] = [7, 8, 9]
657+
assert all(sliced_series[:3] == [7, 8, 9])

0 commit comments

Comments
 (0)