Skip to content

Commit 7bce39b

Browse files
committed
Merge pull request #9659 from jreback/setting_with_copy
API: spurious setting_with_copy warning (GH8730)
2 parents 8f422e2 + f789630 commit 7bce39b

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

doc/source/whatsnew/v0.16.0.txt

+9
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ Other API Changes
454454

455455
To reproduce the old behavior, simply add more precision to the label (e.g., use ``2000-02-01`` instead of ``2000-02``).
456456

457+
- A Spurious ``SettingWithCopy`` Warning was generated when setting a new item in a frame in some cases (:issue:`8730`)
458+
459+
The following would previously report a ``SettingWithCopy`` Warning.
460+
461+
.. ipython:: python
462+
463+
df1 = DataFrame({'x': Series(['a','b','c']), 'y': Series(['d','e','f'])})
464+
df2 = df1[['x']]
465+
df2['y'] = ['g', 'h', 'i']
457466

458467
.. _whatsnew_0160.deprecations:
459468

pandas/core/generic.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,14 @@ def _check_setitem_copy(self, stacklevel=4, t='setting', force=False):
12651265
except:
12661266
pass
12671267

1268+
# we might be a false positive
1269+
try:
1270+
if self.is_copy().shape == self.shape:
1271+
self.is_copy = None
1272+
return
1273+
except:
1274+
pass
1275+
12681276
# a custom message
12691277
if isinstance(self.is_copy, string_types):
12701278
t = self.is_copy
@@ -1344,8 +1352,9 @@ def take(self, indices, axis=0, convert=True, is_copy=True):
13441352
result = self._constructor(new_data).__finalize__(self)
13451353

13461354
# maybe set copy if we didn't actually change the index
1347-
if is_copy and not result._get_axis(axis).equals(self._get_axis(axis)):
1348-
result._set_is_copy(self)
1355+
if is_copy:
1356+
if not result._get_axis(axis).equals(self._get_axis(axis)):
1357+
result._set_is_copy(self)
13491358

13501359
return result
13511360

pandas/tests/test_indexing.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -3751,14 +3751,6 @@ def f():
37513751
assert_series_equal(s,df.iloc[:,0].order())
37523752
assert_series_equal(s,df[0].order())
37533753

3754-
# operating on a copy
3755-
df = pd.DataFrame({'a': list(range(4)), 'b': list('ab..'), 'c': ['a', 'b', np.nan, 'd']})
3756-
mask = pd.isnull(df.c)
3757-
3758-
def f():
3759-
df[['c']][mask] = df[['b']][mask]
3760-
self.assertRaises(com.SettingWithCopyError, f)
3761-
37623754
# false positives GH6025
37633755
df = DataFrame ({'column1':['a', 'a', 'a'], 'column2': [4,8,9] })
37643756
str(df)
@@ -3790,6 +3782,24 @@ def f():
37903782
df['C'][2] = 'foo'
37913783
self.assertRaises(com.SettingWithCopyError, f)
37923784

3785+
def test_setting_with_copy_bug(self):
3786+
3787+
# operating on a copy
3788+
df = pd.DataFrame({'a': list(range(4)), 'b': list('ab..'), 'c': ['a', 'b', np.nan, 'd']})
3789+
mask = pd.isnull(df.c)
3790+
3791+
def f():
3792+
df[['c']][mask] = df[['b']][mask]
3793+
self.assertRaises(com.SettingWithCopyError, f)
3794+
3795+
# invalid warning as we are returning a new object
3796+
# GH 8730
3797+
df1 = DataFrame({'x': Series(['a','b','c']), 'y': Series(['d','e','f'])})
3798+
df2 = df1[['x']]
3799+
3800+
# this should not raise
3801+
df2['y'] = ['g', 'h', 'i']
3802+
37933803
def test_detect_chained_assignment_warnings(self):
37943804

37953805
# warnings

0 commit comments

Comments
 (0)