Skip to content

Commit 09b41ab

Browse files
committed
API/BUG: .apply will correctly infer output shape when axis=1
closes pandas-dev#16353 closes pandas-dev#17348 closes pandas-dev#17437 closes pandas-dev#18573 closes pandas-dev#17970 closes pandas-dev#17892 closes pandas-dev#17602 closes pandas-dev#18775 closes pandas-dev#18901 closes pandas-dev#18919
1 parent 54f1b3e commit 09b41ab

File tree

8 files changed

+636
-168
lines changed

8 files changed

+636
-168
lines changed

doc/source/whatsnew/v0.23.0.txt

+56-2
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ Previous Behavior:
142142
4 NaN
143143
dtype: float64
144144

145-
Current Behavior
145+
Current Behavior:
146146

147147
.. ipython:: python
148148

@@ -167,7 +167,7 @@ Previous Behavior:
167167
3 2.5
168168
dtype: float64
169169

170-
Current Behavior
170+
Current Behavior:
171171

172172
.. ipython:: python
173173

@@ -332,6 +332,59 @@ Convert to an xarray DataArray
332332

333333
p.to_xarray()
334334

335+
.. _whatsnew_0230.api_breaking.apply:
336+
337+
Apply Changes
338+
~~~~~~~~~~~~~
339+
340+
:func:`DataFrame.apply` was inconsistent when applying an arbitrary user-defined-function that returned a list-like with ``axis=1``. Several bugs and inconsistencies
341+
are resolved. If the applied function returns a Series, then pandas will return a DataFrame; otherwise a Series will be returned, this includes the case
342+
where a list-like (e.g. ``tuple`` or ``list`` is returned), (:issue:`16353`, :issue:`17437`, :issue:`17970`, :issue:`17348`, :issue:`17892`, :issue:`18573`,
343+
:issue:`17602`, :issue:`18775`, :issue:`18901`, :issue:`18919`)
344+
345+
.. ipython:: python
346+
347+
df = pd.DataFrame(np.tile(np.arange(3), 6).reshape(6, -1) + 1, columns=['A', 'B', 'C'])
348+
df
349+
350+
Previous Behavior. If the returned shape happened to match the index, this would return a list-like.
351+
352+
.. code-block:: python
353+
354+
In [3]: df.apply(lambda x: [1, 2, 3], axis=1)
355+
Out[3]:
356+
A B C
357+
0 1 2 3
358+
1 1 2 3
359+
2 1 2 3
360+
3 1 2 3
361+
4 1 2 3
362+
5 1 2 3
363+
364+
In [4]: df.apply(lambda x: [1, 2], axis=1)
365+
Out[4]:
366+
0 [1, 2]
367+
1 [1, 2]
368+
2 [1, 2]
369+
3 [1, 2]
370+
4 [1, 2]
371+
5 [1, 2]
372+
dtype: object
373+
374+
375+
New Behavior. The behavior is consistent. These will *always* return a ``Series``.
376+
377+
.. ipython:: python
378+
379+
df.apply(lambda x: [1, 2, 3], axis=1)
380+
df.apply(lambda x: [1, 2], axis=1)
381+
382+
To have automatic inference, you can use ``result_type='infer'``
383+
384+
.. ipython:: python
385+
386+
df.apply(lambda x: [1, 2, 3], axis=1, result_type='infer')
387+
335388

336389
.. _whatsnew_0230.api_breaking.build_changes:
337390

@@ -456,6 +509,7 @@ Deprecations
456509
- The ``is_copy`` attribute is deprecated and will be removed in a future version (:issue:`18801`).
457510
- ``IntervalIndex.from_intervals`` is deprecated in favor of the :class:`IntervalIndex` constructor (:issue:`19263`)
458511
- :func:``DataFrame.from_items`` is deprecated. Use :func:``DataFrame.from_dict()`` instead, or :func:``DataFrame.from_dict(OrderedDict())`` if you wish to preserve the key order (:issue:`17320`)
512+
- The ``broadcast`` parameter of ``.apply()`` is removed in favor of ``result_type='broadcast'`` (:issue:`18577`)
459513

460514
.. _whatsnew_0230.prior_deprecations:
461515

0 commit comments

Comments
 (0)