Skip to content

Commit df7a868

Browse files
committed
Fix Series._slice to free memory by copying underlying data
1 parent 9c5b9ee commit df7a868

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

pandas/core/series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ def _slice(self, slobj: slice, axis: AxisInt = 0) -> Series:
928928
# axis kwarg is retained for compat with NDFrame method
929929
# _slice is *always* positional
930930
mgr = self._mgr.get_slice(slobj, axis=axis)
931-
out = self._constructor_from_mgr(mgr, axes=mgr.axes)
931+
out = self._constructor_from_mgr(mgr, axes=mgr.axes).copy(deep=True)
932932
out._name = self._name
933933
return out.__finalize__(self)
934934

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import gc
2+
import pandas as pd
3+
from pandas import Series
4+
5+
6+
class Dummy:
7+
def __init__(self, val):
8+
self.val = val
9+
10+
11+
def count_dummy_instances():
12+
gc.collect()
13+
return sum(1 for obj in gc.get_objects() if isinstance(obj, Dummy))
14+
15+
16+
def test_slicing_releases_dummy_instances():
17+
"""Ensure that slicing a Series does not retain references to all original Dummy instances."""
18+
NDATA = 100_000
19+
baseline = count_dummy_instances()
20+
a = Series([Dummy(i) for i in range(NDATA)])
21+
a = a[-1:]
22+
gc.collect()
23+
after = count_dummy_instances()
24+
retained = after - baseline
25+
assert (
26+
retained <= 1
27+
), f"{retained} Dummy instances were retained; expected at most 1"

0 commit comments

Comments
 (0)