Skip to content

DOC clarify inplace operation section in 1.5 whats_new #47433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 30, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 55 additions & 36 deletions doc/source/whatsnew/v1.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

@lesteve lesteve Jun 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side-comment: the _ see also ... line is not rendered in the HTML, not sure whether it was supposed to be a link to https://pandas.pydata.org/docs/dev/whatsnew/v1.3.0.html#try-operating-inplace-when-setting-values-with-loc-and-iloc

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it looks like it's supposed to reference that section. Mind correcting it? Can be in the body of the paragraph too like Please reference `this section <whatsnew_130.notable_bug_fixes.setitem_column_try_inplace>` of the 1.3 whatsnew file.


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.
Expand All @@ -605,39 +611,52 @@ iloc will attempt to operate inplace.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth adding ...an entire column with different type with iloc... to the comment above?

.. 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:

Expand Down