Skip to content

Commit 1a68b73

Browse files
committed
CLN: cache indexers in internal_names_set (reported GH5727)
1 parent e89ebae commit 1a68b73

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

pandas/core/generic.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -721,13 +721,13 @@ def __setstate__(self, state):
721721
# to avoid definitional recursion
722722
# e.g. say fill_value needing _data to be
723723
# defined
724-
for k in self._internal_names:
724+
for k in self._internal_names_set:
725725
if k in state:
726726
v = state[k]
727727
object.__setattr__(self, k, v)
728728

729729
for k, v in state.items():
730-
if k not in self._internal_names:
730+
if k not in self._internal_names_set:
731731
object.__setattr__(self, k, v)
732732

733733
else:
@@ -938,15 +938,22 @@ def to_clipboard(self, excel=None, sep=None, **kwargs):
938938
@classmethod
939939
def _create_indexer(cls, name, indexer):
940940
""" create an indexer like _name in the class """
941-
iname = '_%s' % name
942-
setattr(cls, iname, None)
943941

944-
def _indexer(self):
945-
if getattr(self, iname, None) is None:
946-
setattr(self, iname, indexer(self, name))
947-
return getattr(self, iname)
942+
if getattr(cls, name, None) is None:
943+
iname = '_%s' % name
944+
setattr(cls, iname, None)
948945

949-
setattr(cls, name, property(_indexer))
946+
def _indexer(self):
947+
i = getattr(self, iname)
948+
if i is None:
949+
i = indexer(self, name)
950+
setattr(self, iname, i)
951+
return i
952+
953+
setattr(cls, name, property(_indexer))
954+
955+
# add to our internal names set
956+
cls._internal_names_set.add(iname)
950957

951958
def get(self, key, default=None):
952959
"""
@@ -1831,9 +1838,9 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
18311838
pad / ffill: propagate last valid observation forward to next valid
18321839
backfill / bfill: use NEXT valid observation to fill gap
18331840
value : scalar, dict, or Series
1834-
Value to use to fill holes (e.g. 0), alternately a dict/Series of
1835-
values specifying which value to use for each index (for a Series) or
1836-
column (for a DataFrame). (values not in the dict/Series will not be
1841+
Value to use to fill holes (e.g. 0), alternately a dict/Series of
1842+
values specifying which value to use for each index (for a Series) or
1843+
column (for a DataFrame). (values not in the dict/Series will not be
18371844
filled). This value cannot be a list.
18381845
axis : {0, 1}, default 0
18391846
0: fill column-by-column
@@ -1845,8 +1852,8 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
18451852
limit : int, default None
18461853
Maximum size gap to forward or backward fill
18471854
downcast : dict, default is None
1848-
a dict of item->dtype of what to downcast if possible,
1849-
or the string 'infer' which will try to downcast to an appropriate
1855+
a dict of item->dtype of what to downcast if possible,
1856+
or the string 'infer' which will try to downcast to an appropriate
18501857
equal type (e.g. float64 to int64 if possible)
18511858
18521859
See also

pandas/tests/test_indexing.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import itertools
44
import warnings
55

6-
from pandas.compat import range, lrange, StringIO, lmap, map
6+
from pandas.compat import range, lrange, lzip, StringIO, lmap, map
77
from numpy import random, nan
88
from numpy.random import randn
99
import numpy as np
@@ -249,6 +249,15 @@ def _print(result, error = None):
249249
k2 = key2
250250
_eq(t, o, a, obj, key1, k2)
251251

252+
def test_indexer_caching(self):
253+
# GH5727
254+
# make sure that indexers are in the _internal_names_set
255+
n = 1000001
256+
arrays = [lrange(n), np.empty(n)]
257+
index = MultiIndex.from_tuples(lzip(*arrays))
258+
s = Series(np.zeros(n), index=index)
259+
str(s)
260+
252261
def test_at_and_iat_get(self):
253262

254263
def _check(f, func, values = False):

0 commit comments

Comments
 (0)