diff --git a/doc/source/whatsnew/v0.15.2.txt b/doc/source/whatsnew/v0.15.2.txt index 8d6e3cb0512b4..944a78ad3691e 100644 --- a/doc/source/whatsnew/v0.15.2.txt +++ b/doc/source/whatsnew/v0.15.2.txt @@ -71,6 +71,7 @@ Bug Fixes - ``Timedelta`` kwargs may now be numpy ints and floats (:issue:`8757`). - ``sql_schema`` now generates dialect appropriate ``CREATE TABLE`` statements (:issue:`8697`) - ``slice`` string method now takes step into account (:issue:`8754`) +- Bug in ``BlockManager`` where setting values with different type would break block integrity (:issue:`8850`) - Fix negative step support for label-based slices (:issue:`8753`) Old behavior: diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 306aebede2476..14c4fb17c2b34 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -2985,7 +2985,7 @@ def value_getitem(placement): loc = [loc] blknos = self._blknos[loc] - blklocs = self._blklocs[loc] + blklocs = self._blklocs[loc].copy() unfit_mgr_locs = [] unfit_val_locs = [] diff --git a/pandas/tests/test_internals.py b/pandas/tests/test_internals.py index 5bc7558efb471..37b557743b731 100644 --- a/pandas/tests/test_internals.py +++ b/pandas/tests/test_internals.py @@ -430,6 +430,17 @@ def test_set_change_dtype(self): mgr2.set('quux', randn(N)) self.assertEqual(mgr2.get('quux').dtype, np.float_) + def test_set_change_dtype_slice(self): # GH8850 + cols = MultiIndex.from_tuples([('1st','a'), ('2nd','b'), ('3rd','c')]) + df = DataFrame([[1.0, 2, 3], [4.0, 5, 6]], columns=cols) + df['2nd'] = df['2nd'] * 2.0 + + self.assertEqual(sorted(df.blocks.keys()), ['float64', 'int64']) + assert_frame_equal(df.blocks['float64'], + DataFrame([[1.0, 4.0], [4.0, 10.0]], columns=cols[:2])) + assert_frame_equal(df.blocks['int64'], + DataFrame([[3], [6]], columns=cols[2:])) + def test_copy(self): shallow = self.mgr.copy(deep=False)