@@ -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 ()
@@ -1019,17 +1027,21 @@ def _setitem_copy(self, copy):
1019
1027
self .is_copy = copy
1020
1028
return self
1021
1029
1022
- def _check_setitem_copy (self , stacklevel = 4 ):
1030
+ def _check_setitem_copy (self , stacklevel = 4 , t = 'setting' ):
1023
1031
""" validate if we are doing a settitem on a chained copy.
1024
1032
1025
1033
If you call this function, be sure to set the stacklevel such that the
1026
1034
user will see the error *at the level of setting*"""
1027
1035
if self .is_copy :
1028
1036
value = config .get_option ('mode.chained_assignment' )
1029
1037
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" )
1038
+ if t == 'referant' :
1039
+ t = ("A value is trying to be set on a copy of a slice from a "
1040
+ "DataFrame" )
1041
+ else :
1042
+ t = ("A value is trying to be set on a copy of a slice from a "
1043
+ "DataFrame.\n Try using .loc[row_index,col_indexer] = value "
1044
+ "instead" )
1033
1045
if value == 'raise' :
1034
1046
raise SettingWithCopyError (t )
1035
1047
elif value == 'warn' :
@@ -1218,7 +1230,7 @@ def _update_inplace(self, result):
1218
1230
# decision that we may revisit in the future.
1219
1231
self ._reset_cache ()
1220
1232
self ._clear_item_cache ()
1221
- self ._data = result . _data
1233
+ self ._data = getattr ( result , ' _data' , result )
1222
1234
self ._maybe_update_cacher ()
1223
1235
1224
1236
def add_prefix (self , prefix ):
@@ -1910,14 +1922,13 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
1910
1922
continue
1911
1923
obj = result [k ]
1912
1924
obj .fillna (v , inplace = True )
1913
- obj ._maybe_update_cacher ()
1914
1925
return result
1915
1926
else :
1916
1927
new_data = self ._data .fillna (value , inplace = inplace ,
1917
1928
downcast = downcast )
1918
1929
1919
1930
if inplace :
1920
- self ._data = new_data
1931
+ self ._update_inplace ( new_data )
1921
1932
else :
1922
1933
return self ._constructor (new_data ).__finalize__ (self )
1923
1934
@@ -2165,7 +2176,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None,
2165
2176
new_data = new_data .convert (copy = not inplace , convert_numeric = False )
2166
2177
2167
2178
if inplace :
2168
- self ._data = new_data
2179
+ self ._update_inplace ( new_data )
2169
2180
else :
2170
2181
return self ._constructor (new_data ).__finalize__ (self )
2171
2182
@@ -2272,10 +2283,10 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False,
2272
2283
2273
2284
if inplace :
2274
2285
if axis == 1 :
2275
- self ._data = new_data
2286
+ self ._update_inplace ( new_data )
2276
2287
self = self .T
2277
2288
else :
2278
- self ._data = new_data
2289
+ self ._update_inplace ( new_data )
2279
2290
else :
2280
2291
res = self ._constructor (new_data ).__finalize__ (self )
2281
2292
if axis == 1 :
@@ -2856,8 +2867,9 @@ def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
2856
2867
if inplace :
2857
2868
# we may have different type blocks come out of putmask, so
2858
2869
# reconstruct the block manager
2859
- self ._data = self ._data .putmask (cond , other , align = axis is None ,
2860
- inplace = True )
2870
+ new_data = self ._data .putmask (cond , other , align = axis is None ,
2871
+ inplace = True )
2872
+ self ._update_inplace (new_data )
2861
2873
2862
2874
else :
2863
2875
new_data = self ._data .where (other , cond , align = axis is None ,
0 commit comments