@@ -59,7 +59,7 @@ def _single_replace(self, to_replace, method, inplace, limit):
59
59
dtype = self .dtype ).__finalize__ (self )
60
60
61
61
if inplace :
62
- self ._data = result ._data
62
+ self ._update_inplace ( result ._data )
63
63
return
64
64
65
65
return result
@@ -562,9 +562,7 @@ def f(x):
562
562
result ._clear_item_cache ()
563
563
564
564
if inplace :
565
- self ._data = result ._data
566
- self ._clear_item_cache ()
567
-
565
+ self ._update_inplace (result ._data )
568
566
else :
569
567
return result .__finalize__ (self )
570
568
@@ -994,12 +992,22 @@ def _maybe_update_cacher(self, clear=False):
994
992
if clear, then clear our cache """
995
993
cacher = getattr (self , '_cacher' , None )
996
994
if cacher is not None :
997
- try :
998
- cacher [1 ]()._maybe_cache_changed (cacher [0 ], self )
999
- except :
995
+ ref = cacher [1 ]()
1000
996
1001
- # our referant is dead
997
+ # we are trying to reference a dead referant, hence
998
+ # a copy
999
+ if ref is None :
1002
1000
del self ._cacher
1001
+ self .is_copy = True
1002
+ self ._check_setitem_copy (stacklevel = 5 , t = 'referant' )
1003
+ else :
1004
+ try :
1005
+ ref ._maybe_cache_changed (cacher [0 ], self )
1006
+ except :
1007
+ pass
1008
+ if ref .is_copy :
1009
+ self .is_copy = True
1010
+ self ._check_setitem_copy (stacklevel = 5 , t = 'referant' )
1003
1011
1004
1012
if clear :
1005
1013
self ._clear_item_cache ()
@@ -1014,22 +1022,21 @@ def _set_item(self, key, value):
1014
1022
self ._data .set (key , value )
1015
1023
self ._clear_item_cache ()
1016
1024
1017
- def _setitem_copy (self , copy ):
1018
- """ set the _is_copy of the iiem """
1019
- self .is_copy = copy
1020
- return self
1021
-
1022
- def _check_setitem_copy (self , stacklevel = 4 ):
1025
+ def _check_setitem_copy (self , stacklevel = 4 , t = 'setting' ):
1023
1026
""" validate if we are doing a settitem on a chained copy.
1024
1027
1025
1028
If you call this function, be sure to set the stacklevel such that the
1026
1029
user will see the error *at the level of setting*"""
1027
1030
if self .is_copy :
1028
1031
value = config .get_option ('mode.chained_assignment' )
1029
1032
1030
- t = ("A value is trying to be set on a copy of a slice from a "
1031
- "DataFrame.\n Try using .loc[row_index,col_indexer] = value "
1032
- "instead" )
1033
+ if t == 'referant' :
1034
+ t = ("A value is trying to be set on a copy of a slice from a "
1035
+ "DataFrame" )
1036
+ else :
1037
+ t = ("A value is trying to be set on a copy of a slice from a "
1038
+ "DataFrame.\n Try using .loc[row_index,col_indexer] = value "
1039
+ "instead" )
1033
1040
if value == 'raise' :
1034
1041
raise SettingWithCopyError (t )
1035
1042
elif value == 'warn' :
@@ -1103,7 +1110,7 @@ def take(self, indices, axis=0, convert=True, is_copy=True):
1103
1110
1104
1111
# maybe set copy if we didn't actually change the index
1105
1112
if is_copy and not result ._get_axis (axis ).equals (self ._get_axis (axis )):
1106
- result = result . _setitem_copy ( is_copy )
1113
+ result . is_copy = is_copy
1107
1114
1108
1115
return result
1109
1116
@@ -1218,7 +1225,7 @@ def _update_inplace(self, result):
1218
1225
# decision that we may revisit in the future.
1219
1226
self ._reset_cache ()
1220
1227
self ._clear_item_cache ()
1221
- self ._data = result . _data
1228
+ self ._data = getattr ( result , ' _data' , result )
1222
1229
self ._maybe_update_cacher ()
1223
1230
1224
1231
def add_prefix (self , prefix ):
@@ -1910,14 +1917,13 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
1910
1917
continue
1911
1918
obj = result [k ]
1912
1919
obj .fillna (v , inplace = True )
1913
- obj ._maybe_update_cacher ()
1914
1920
return result
1915
1921
else :
1916
1922
new_data = self ._data .fillna (value , inplace = inplace ,
1917
1923
downcast = downcast )
1918
1924
1919
1925
if inplace :
1920
- self ._data = new_data
1926
+ self ._update_inplace ( new_data )
1921
1927
else :
1922
1928
return self ._constructor (new_data ).__finalize__ (self )
1923
1929
@@ -2165,7 +2171,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
2165
2171
new_data = new_data .convert (copy = not inplace , convert_numeric = False )
2166
2172
2167
2173
if inplace :
2168
- self ._data = new_data
2174
+ self ._update_inplace ( new_data )
2169
2175
else :
2170
2176
return self ._constructor (new_data ).__finalize__ (self )
2171
2177
@@ -2272,10 +2278,10 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False,
2272
2278
2273
2279
if inplace :
2274
2280
if axis == 1 :
2275
- self ._data = new_data
2281
+ self ._update_inplace ( new_data )
2276
2282
self = self .T
2277
2283
else :
2278
- self ._data = new_data
2284
+ self ._update_inplace ( new_data )
2279
2285
else :
2280
2286
res = self ._constructor (new_data ).__finalize__ (self )
2281
2287
if axis == 1 :
@@ -2856,8 +2862,9 @@ def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
2856
2862
if inplace :
2857
2863
# we may have different type blocks come out of putmask, so
2858
2864
# reconstruct the block manager
2859
- self ._data = self ._data .putmask (cond , other , align = axis is None ,
2860
- inplace = True )
2865
+ new_data = self ._data .putmask (cond , other , align = axis is None ,
2866
+ inplace = True )
2867
+ self ._update_inplace (new_data )
2861
2868
2862
2869
else :
2863
2870
new_data = self ._data .where (other , cond , align = axis is None ,
0 commit comments