Skip to content

Commit 8e4a32c

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 bc1d027 commit 8e4a32c

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

@@ -288,6 +288,59 @@ Convert to an xarray DataArray
288288

289289
p.to_xarray()
290290

291+
.. _whatsnew_0230.api_breaking.apply:
292+
293+
Apply Changes
294+
~~~~~~~~~~~~~
295+
296+
:func:`DataFrame.apply` was inconsistent when applying an arbitrary user-defined-function that returned a list-like with ``axis=1``. Several bugs and inconsistencies
297+
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
298+
where a list-like (e.g. ``tuple`` or ``list`` is returned), (:issue:`16353`, :issue:`17437`, :issue:`17970`, :issue:`17348`, :issue:`17892`, :issue:`18573`,
299+
:issue:`17602`, :issue:`18775`, :issue:`18901`, :issue:`18919`)
300+
301+
.. ipython:: python
302+
303+
df = pd.DataFrame(np.tile(np.arange(3), 6).reshape(6, -1) + 1, columns=['A', 'B', 'C'])
304+
df
305+
306+
Previous Behavior. If the returned shape happened to match the index, this would return a list-like.
307+
308+
.. code-block:: python
309+
310+
In [3]: df.apply(lambda x: [1, 2, 3], axis=1)
311+
Out[3]:
312+
A B C
313+
0 1 2 3
314+
1 1 2 3
315+
2 1 2 3
316+
3 1 2 3
317+
4 1 2 3
318+
5 1 2 3
319+
320+
In [4]: df.apply(lambda x: [1, 2], axis=1)
321+
Out[4]:
322+
0 [1, 2]
323+
1 [1, 2]
324+
2 [1, 2]
325+
3 [1, 2]
326+
4 [1, 2]
327+
5 [1, 2]
328+
dtype: object
329+
330+
331+
New Behavior. The behavior is consistent. These will *always* return a ``Series``.
332+
333+
.. ipython:: python
334+
335+
df.apply(lambda x: [1, 2, 3], axis=1)
336+
df.apply(lambda x: [1, 2], axis=1)
337+
338+
To have automatic inference, you can use ``result_type='infer'``
339+
340+
.. ipython:: python
341+
342+
df.apply(lambda x: [1, 2, 3], axis=1, result_type='infer')
343+
291344

292345
Build Changes
293346
^^^^^^^^^^^^^
@@ -361,6 +414,7 @@ Deprecations
361414
- The ``is_copy`` attribute is deprecated and will be removed in a future version (:issue:`18801`).
362415
- ``IntervalIndex.from_intervals`` is deprecated in favor of the :class:`IntervalIndex` constructor (:issue:`19263`)
363416
- :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`)
417+
- The ``broadcast`` parameter of ``.apply()`` is removed in favor of ``result_type='broadcast'`` (:issue:`18577`)
364418

365419
.. _whatsnew_0230.prior_deprecations:
366420

0 commit comments

Comments
 (0)