From 902142be1220dec1394468f717fb0b640dbc80d3 Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Fri, 5 Jun 2020 14:26:07 +0100 Subject: [PATCH 1/3] BUG: Pandas changes dtypes of columns when no float (or other) assignments are done to this column #34573 --- doc/source/whatsnew/v1.1.0.rst | 1 + pandas/core/indexing.py | 3 ++- pandas/tests/frame/indexing/test_setitem.py | 24 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index b4e29291bb12d..9594e36e15324 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -887,6 +887,7 @@ Indexing - Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` where index was assumed to be monotone increasing (:issue:`33756`) - Indexing with a list of strings representing datetimes failed on :class:`DatetimeIndex` or :class:`PeriodIndex`(:issue:`11278`) - Bug in :meth:`Series.at` when used with a :class:`MultiIndex` would raise an exception on valid inputs (:issue:`26989`) +- BUG in :meth:`DataFrame.loc` with dictionary of values changes columns with dtype of ``int`` to ``float`` (:issue:`34573`) Missing ^^^^^^^ diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 60312c6e3b6d7..18897fa1e0551 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1840,7 +1840,8 @@ def _setitem_with_indexer_missing(self, indexer, value): if len(value) != len(self.obj.columns): raise ValueError("cannot set a row with mismatched columns") - value = Series(value, index=self.obj.columns, name=indexer) + dtype = object if isinstance(value, dict) else None + value = Series(value, index=self.obj.columns, name=indexer, dtype=dtype) self.obj._mgr = self.obj.append(value)._mgr self.obj._maybe_update_cacher(clear=True) diff --git a/pandas/tests/frame/indexing/test_setitem.py b/pandas/tests/frame/indexing/test_setitem.py index d53665539309c..8fcdae95fbab5 100644 --- a/pandas/tests/frame/indexing/test_setitem.py +++ b/pandas/tests/frame/indexing/test_setitem.py @@ -126,3 +126,27 @@ def test_setitem_with_unaligned_sparse_value(self): df["new_column"] = sp_series expected = Series(SparseArray([1, 0, 0]), name="new_column") tm.assert_series_equal(df["new_column"], expected) + + def test_setitem_dict_preserves_dtypes(self): + # https://github.com/pandas-dev/pandas/issues/34573 + expected = DataFrame( + { + "a": Series([0, 1, 2], dtype="int64"), + "b": Series([1, 2, 3], dtype=float), + "c": Series([1, 2, 3], dtype=float), + } + ) + df = DataFrame( + { + "a": Series([], dtype="int64"), + "b": Series([], dtype=float), + "c": Series([], dtype=float), + } + ) + for idx, b in enumerate([1, 2, 3]): + df.loc[df.shape[0]] = { + "a": int(idx), + "b": float(b), + "c": float(b), + } + tm.assert_frame_equal(df, expected) From a31be63abe87f260c075d1805348e9cae7c28710 Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Fri, 5 Jun 2020 20:18:49 +0100 Subject: [PATCH 2/3] typo --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index f1120f69f8f38..1ff717a743162 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -892,7 +892,7 @@ Indexing - Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` where index was assumed to be monotone increasing (:issue:`33756`) - Indexing with a list of strings representing datetimes failed on :class:`DatetimeIndex` or :class:`PeriodIndex`(:issue:`11278`) - Bug in :meth:`Series.at` when used with a :class:`MultiIndex` would raise an exception on valid inputs (:issue:`26989`) -- BUG in :meth:`DataFrame.loc` with dictionary of values changes columns with dtype of ``int`` to ``float`` (:issue:`34573`) +- Bug in :meth:`DataFrame.loc` with dictionary of values changes columns with dtype of ``int`` to ``float`` (:issue:`34573`) - Bug in :meth:`Series.loc` when used with a :class:`MultiIndex` would raise an IndexingError when accessing a None value (:issue:`34318`) Missing From 7313cabaaedc0cd3f3f38b0f9154222042a40c54 Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Tue, 9 Jun 2020 12:24:14 +0100 Subject: [PATCH 3/3] update per comment --- pandas/core/indexing.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index c94246d117233..326bd00270eca 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1836,7 +1836,10 @@ def _setitem_with_indexer_missing(self, indexer, value): # append a Series value = value.reindex(index=self.obj.columns, copy=True) value.name = indexer - + elif isinstance(value, dict): + value = Series( + value, index=self.obj.columns, name=indexer, dtype=object + ) else: # a list-list if is_list_like_indexer(value): @@ -1844,8 +1847,7 @@ def _setitem_with_indexer_missing(self, indexer, value): if len(value) != len(self.obj.columns): raise ValueError("cannot set a row with mismatched columns") - dtype = object if isinstance(value, dict) else None - value = Series(value, index=self.obj.columns, name=indexer, dtype=dtype) + value = Series(value, index=self.obj.columns, name=indexer) self.obj._mgr = self.obj.append(value)._mgr self.obj._maybe_update_cacher(clear=True)