From 3749e9ae1d93452e1a0c0add18be5b6583d63ebd Mon Sep 17 00:00:00 2001 From: jreback Date: Tue, 14 Jan 2014 16:10:04 -0500 Subject: [PATCH] API: Raise/Warn SettingWithCopyError (according to the option chained_assignment in more cases, when detecting chained assignment, related (GH5938) --- doc/source/release.rst | 8 +++++--- pandas/core/frame.py | 3 +++ pandas/tests/test_indexing.py | 8 ++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/doc/source/release.rst b/doc/source/release.rst index 589dcca154a10..aa772ef437355 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -58,8 +58,9 @@ API Changes - ``Series.sort`` will raise a ``ValueError`` (rather than a ``TypeError``) on sorting an object that is a view of another (:issue:`5856`, :issue:`5853`) - -.. _release.bug_fixes-0.13.1: + - Raise/Warn ``SettingWithCopyError`` (according to the option ``chained_assignment`` in more cases, + when detecting chained assignment, related (:issue:`5938`) + - DataFrame.head(0) returns self instead of empty frame (:issue:`5846`) Experimental Features ~~~~~~~~~~~~~~~~~~~~~ @@ -72,7 +73,8 @@ Improvements to existing features - df.info() view now display dtype info per column (:issue: `5682`) - perf improvements in DataFrame ``count/dropna`` for ``axis=1`` - Series.str.contains now has a `regex=False` keyword which can be faster for plain (non-regex) string patterns. (:issue: `5879`) - - DataFrame.head(0) returns self instead of empty frame (:issue:`5846`) + +.. _release.bug_fixes-0.13.1: Bug Fixes ~~~~~~~~~ diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 47ec392a1135a..8f1916141b572 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1856,6 +1856,7 @@ def _box_col_values(self, values, items): name=items, fastpath=True) def __setitem__(self, key, value): + # see if we can slice the rows indexer = _convert_to_index_sliceable(self, key) if indexer is not None: @@ -1880,6 +1881,7 @@ def _setitem_array(self, key, value): (len(key), len(self.index))) key = _check_bool_indexer(self.index, key) indexer = key.nonzero()[0] + self._check_setitem_copy() self.ix._setitem_with_indexer(indexer, value) else: if isinstance(value, DataFrame): @@ -1889,6 +1891,7 @@ def _setitem_array(self, key, value): self[k1] = value[k2] else: indexer = self.ix._convert_to_indexer(key, axis=1) + self._check_setitem_copy() self.ix._setitem_with_indexer((slice(None), indexer), value) def _setitem_frame(self, key, value): diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index 1a7359eed45fc..8f3f122fefb88 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -2061,6 +2061,14 @@ def f(): assert_series_equal(s,df.iloc[:,0].order()) assert_series_equal(s,df[0].order()) + # operating on a copy + df = pd.DataFrame({'a': list(range(4)), 'b': list('ab..'), 'c': ['a', 'b', np.nan, 'd']}) + mask = pd.isnull(df.c) + + def f(): + df[['c']][mask] = df[['b']][mask] + self.assertRaises(com.SettingWithCopyError, f) + pd.set_option('chained_assignment','warn') def test_float64index_slicing_bug(self):