diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index a4fa31f7fc368..499e410cb81fd 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -572,31 +572,37 @@ As ``group_keys=True`` is the default value of :meth:`DataFrame.groupby` and raise a ``FutureWarning``. This can be silenced and the previous behavior retained by specifying ``group_keys=False``. -.. _whatsnew_150.notable_bug_fixes.setitem_column_try_inplace: +.. _whatsnew_150.deprecations.setitem_column_try_inplace: _ see also _whatsnew_130.notable_bug_fixes.setitem_column_try_inplace -Try operating inplace when setting values with ``loc`` and ``iloc`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Inplace operation when setting values with ``loc`` and ``iloc`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Most of the time setting values with ``frame.iloc`` attempts to set values -in-place, only falling back to inserting a new array if necessary. In the past, -setting entire columns has been an exception to this rule: +inplace, only falling back to inserting a new array if necessary. There are +some cases where this rule is not followed, for example when setting an entire +column from an array with different dtype: .. ipython:: python - values = np.arange(4).reshape(2, 2) - df = pd.DataFrame(values) - ser = df[0] + df = pd.DataFrame({'price': [11.1, 12.2]}, index=['book1', 'book2']) + original_prices = df['price'] + new_prices = np.array([98, 99]) *Old behavior*: .. code-block:: ipython - In [3]: df.iloc[:, 0] = np.array([10, 11]) - In [4]: ser + In [3]: df.iloc[:, 0] = new_prices + In [4]: df.iloc[:, 0] Out[4]: - 0 0 - 1 2 - Name: 0, dtype: int64 + book1 98 + book2 99 + Name: price, dtype: int64 + In [5]: original_prices + Out[5]: + book1 11.1 + book2 12.2 + Name: price, float: 64 This behavior is deprecated. In a future version, setting an entire column with iloc will attempt to operate inplace. @@ -605,39 +611,52 @@ iloc will attempt to operate inplace. .. code-block:: ipython - In [3]: df.iloc[:, 0] = np.array([10, 11]) - In [4]: ser + In [3]: df.iloc[:, 0] = new_prices + In [4]: df.iloc[:, 0] Out[4]: - 0 10 - 1 11 - Name: 0, dtype: int64 + book1 98.0 + book2 99.0 + Name: price, dtype: float64 + In [5]: original_prices + Out[5]: + book1 98.0 + book2 99.0 + Name: price, dtype: float64 To get the old behavior, use :meth:`DataFrame.__setitem__` directly: -*Future behavior*: - .. code-block:: ipython - In [5]: df[0] = np.array([21, 31]) - In [4]: ser - Out[4]: - 0 10 - 1 11 - Name: 0, dtype: int64 - -In the case where ``df.columns`` is not unique, use :meth:`DataFrame.isetitem`: - -*Future behavior*: + In [3]: df[df.columns[0]] = new_prices + In [4]: df.iloc[:, 0] + Out[4] + book1 98 + book2 99 + Name: price, dtype: int64 + In [5]: original_prices + Out[5]: + book1 11.1 + book2 12.2 + Name: price, dtype: float64 + +To get the old behaviour when ``df.columns`` is not unique and you want to +change a single column by index, you can use :meth:`DataFrame.isetitem`, which +has been added in pandas 1.5: .. code-block:: ipython - In [5]: df.columns = ["A", "A"] - In [5]: df.isetitem(0, np.array([21, 31])) - In [4]: ser + In [3]: df_with_duplicated_cols = pd.concat([df, df], axis='columns') + In [3]: df_with_duplicated_cols.isetitem(0, new_prices) + In [4]: df_with_duplicated_cols.iloc[:, 0] Out[4]: - 0 10 - 1 11 - Name: 0, dtype: int64 + book1 98 + book2 99 + Name: price, dtype: int64 + In [5]: original_prices + Out[5]: + book1 11.1 + book2 12.2 + Name: 0, dtype: float64 .. _whatsnew_150.deprecations.numeric_only_default: