Skip to content

Commit dbb7d12

Browse files
committed
Merge branch 'master' into feature/groupby-repr-ellipses-1135
2 parents 33142cb + 3e652ac commit dbb7d12

File tree

14 files changed

+107
-827
lines changed

14 files changed

+107
-827
lines changed

doc/source/whatsnew/v0.24.2.rst

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ Fixed Regressions
2424
- Fixed issue in ``DataFrame`` construction with passing a mixed list of mixed types could segfault. (:issue:`25075`)
2525
- Fixed regression in :meth:`DataFrame.apply` causing ``RecursionError`` when ``dict``-like classes were passed as argument. (:issue:`25196`)
2626
- Fixed regression in :meth:`DataFrame.replace` where ``regex=True`` was only replacing patterns matching the start of the string (:issue:`25259`)
27-
2827
- Fixed regression in :meth:`DataFrame.duplicated()`, where empty dataframe was not returning a boolean dtyped Series. (:issue:`25184`)
29-
- Fixed regression in :meth:`Series.min` and :meth:`Series.max` where ``numeric_only=True`` was ignored when the ``Series`` contained ```Categorical`` data (:issue:`25299`)
30-
- Fixed regression in subtraction between :class:`Series` objects with ``datetime64[ns]`` dtype incorrectly raising ``OverflowError`` when the `Series` on the right contains null values (:issue:`25317`)
31-
- Fixed regression in :class:`TimedeltaIndex` where `np.sum(index)` incorrectly returned a zero-dimensional object instead of a scalar (:issue:`25282`)
28+
- Fixed regression in :meth:`Series.min` and :meth:`Series.max` where ``numeric_only=True`` was ignored when the ``Series`` contained ``Categorical`` data (:issue:`25299`)
29+
- Fixed regression in subtraction between :class:`Series` objects with ``datetime64[ns]`` dtype incorrectly raising ``OverflowError`` when the ``Series`` on the right contains null values (:issue:`25317`)
30+
- Fixed regression in :class:`TimedeltaIndex` where ``np.sum(index)`` incorrectly returned a zero-dimensional object instead of a scalar (:issue:`25282`)
3231
- Fixed regression in ``IntervalDtype`` construction where passing an incorrect string with 'Interval' as a prefix could result in a ``RecursionError``. (:issue:`25338`)
33-
3432
- Fixed regression in :class:`Categorical`, where constructing it from a categorical ``Series`` and an explicit ``categories=`` that differed from that in the ``Series`` created an invalid object which could trigger segfaults. (:issue:`25318`)
3533

3634
.. _whatsnew_0242.enhancements:
@@ -60,7 +58,7 @@ Bug Fixes
6058

6159
**I/O**
6260

63-
- Better handling of terminal printing when the terminal dimensions are not known (:issue:`25080`);
61+
- Better handling of terminal printing when the terminal dimensions are not known (:issue:`25080`)
6462
- Bug in reading a HDF5 table-format ``DataFrame`` created in Python 2, in Python 3 (:issue:`24925`)
6563
- Bug in reading a JSON with ``orient='table'`` generated by :meth:`DataFrame.to_json` with ``index=False`` (:issue:`25170`)
6664
- Bug where float indexes could have misaligned values when printing (:issue:`25061`)
@@ -86,7 +84,7 @@ Bug Fixes
8684

8785
**Reshaping**
8886

89-
- Bug in :meth:`pandas.core.groupby.GroupBy.transform` where applying a function to a timezone aware column would return a timezone naive result (:issue:`24198`)
87+
- Bug in :meth:`~pandas.core.groupby.GroupBy.transform` where applying a function to a timezone aware column would return a timezone naive result (:issue:`24198`)
9088
- Bug in :func:`DataFrame.join` when joining on a timezone aware :class:`DatetimeIndex` (:issue:`23931`)
9189
-
9290

@@ -103,7 +101,7 @@ Bug Fixes
103101
- Bug in ``IntervalTree`` where a ``RecursionError`` occurs upon construction due to an overflow when adding endpoints, which also causes :class:`IntervalIndex` to crash during indexing operations (:issue:`25485`)
104102
-
105103

106-
.. _whatsnew_0.242.contributors:
104+
.. _whatsnew_0242.contributors:
107105

108106
Contributors
109107
~~~~~~~~~~~~

doc/source/whatsnew/v0.25.0.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Other Enhancements
2525
- ``Series.str`` has gained :meth:`Series.str.casefold` method to removes all case distinctions present in a string (:issue:`25405`)
2626
- :meth:`DataFrame.set_index` now works for instances of ``abc.Iterator``, provided their output is of the same length as the calling frame (:issue:`22484`, :issue:`24984`)
2727
- :meth:`DatetimeIndex.union` now supports the ``sort`` argument. The behaviour of the sort parameter matches that of :meth:`Index.union` (:issue:`24994`)
28-
-
28+
- :meth:`DataFrame.rename` now supports the ``errors`` argument to raise errors when attempting to rename nonexistent keys (:issue:`13473`)
2929

3030
.. _whatsnew_0250.api_breaking:
3131

@@ -150,7 +150,7 @@ Timezones
150150

151151
- Bug in :func:`to_datetime` with ``utc=True`` and datetime strings that would apply previously parsed UTC offsets to subsequent arguments (:issue:`24992`)
152152
- Bug in :func:`Timestamp.tz_localize` and :func:`Timestamp.tz_convert` does not propagate ``freq`` (:issue:`25241`)
153-
-
153+
- Bug in :func:`Series.at` where setting :class:`Timestamp` with timezone raises ``TypeError`` (:issue:`25506`)
154154

155155
Numeric
156156
^^^^^^^

pandas/core/frame.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3911,7 +3911,8 @@ def drop(self, labels=None, axis=0, index=None, columns=None,
39113911

39123912
@rewrite_axis_style_signature('mapper', [('copy', True),
39133913
('inplace', False),
3914-
('level', None)])
3914+
('level', None),
3915+
('errors', 'ignore')])
39153916
def rename(self, *args, **kwargs):
39163917
"""
39173918
Alter axes labels.
@@ -3924,30 +3925,49 @@ def rename(self, *args, **kwargs):
39243925
39253926
Parameters
39263927
----------
3927-
mapper, index, columns : dict-like or function, optional
3928-
dict-like or functions transformations to apply to
3928+
mapper : dict-like or function
3929+
Dict-like or functions transformations to apply to
39293930
that axis' values. Use either ``mapper`` and ``axis`` to
39303931
specify the axis to target with ``mapper``, or ``index`` and
39313932
``columns``.
3932-
axis : int or str, optional
3933+
index : dict-like or function
3934+
Alternative to specifying axis (``mapper, axis=0``
3935+
is equivalent to ``index=mapper``).
3936+
columns : dict-like or function
3937+
Alternative to specifying axis (``mapper, axis=1``
3938+
is equivalent to ``columns=mapper``).
3939+
axis : int or str
39333940
Axis to target with ``mapper``. Can be either the axis name
39343941
('index', 'columns') or number (0, 1). The default is 'index'.
3935-
copy : boolean, default True
3936-
Also copy underlying data
3937-
inplace : boolean, default False
3942+
copy : bool, default True
3943+
Also copy underlying data.
3944+
inplace : bool, default False
39383945
Whether to return a new DataFrame. If True then value of copy is
39393946
ignored.
39403947
level : int or level name, default None
39413948
In case of a MultiIndex, only rename labels in the specified
39423949
level.
3950+
errors : {'ignore', 'raise'}, default 'ignore'
3951+
If 'raise', raise a `KeyError` when a dict-like `mapper`, `index`,
3952+
or `columns` contains labels that are not present in the Index
3953+
being transformed.
3954+
If 'ignore', existing keys will be renamed and extra keys will be
3955+
ignored.
39433956
39443957
Returns
39453958
-------
39463959
DataFrame
3960+
DataFrame with the renamed axis labels.
3961+
3962+
Raises
3963+
------
3964+
KeyError
3965+
If any of the labels is not found in the selected axis and
3966+
"errors='raise'".
39473967
39483968
See Also
39493969
--------
3950-
DataFrame.rename_axis
3970+
DataFrame.rename_axis : Set the name of the axis.
39513971
39523972
Examples
39533973
--------
@@ -3973,6 +3993,10 @@ def rename(self, *args, **kwargs):
39733993
1 2 5
39743994
2 3 6
39753995
3996+
>>> df.rename(index=str, columns={"A": "a", "C": "c"}, errors="raise")
3997+
Traceback (most recent call last):
3998+
KeyError: ['C'] not found in axis
3999+
39764000
Using axis-style parameters
39774001
39784002
>>> df.rename(str.lower, axis='columns')

pandas/core/generic.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,11 +981,23 @@ def rename(self, *args, **kwargs):
981981
level : int or level name, default None
982982
In case of a MultiIndex, only rename labels in the specified
983983
level.
984+
errors : {'ignore', 'raise'}, default 'ignore'
985+
If 'raise', raise a `KeyError` when a dict-like `mapper`, `index`,
986+
or `columns` contains labels that are not present in the Index
987+
being transformed.
988+
If 'ignore', existing keys will be renamed and extra keys will be
989+
ignored.
984990
985991
Returns
986992
-------
987993
renamed : %(klass)s (new object)
988994
995+
Raises
996+
------
997+
KeyError
998+
If any of the labels is not found in the selected axis and
999+
"errors='raise'".
1000+
9891001
See Also
9901002
--------
9911003
NDFrame.rename_axis
@@ -1065,6 +1077,7 @@ def rename(self, *args, **kwargs):
10651077
inplace = kwargs.pop('inplace', False)
10661078
level = kwargs.pop('level', None)
10671079
axis = kwargs.pop('axis', None)
1080+
errors = kwargs.pop('errors', 'ignore')
10681081
if axis is not None:
10691082
# Validate the axis
10701083
self._get_axis_number(axis)
@@ -1085,10 +1098,19 @@ def rename(self, *args, **kwargs):
10851098
if v is None:
10861099
continue
10871100
f = com._get_rename_function(v)
1088-
10891101
baxis = self._get_block_manager_axis(axis)
10901102
if level is not None:
10911103
level = self.axes[axis]._get_level_number(level)
1104+
1105+
# GH 13473
1106+
if not callable(v):
1107+
indexer = self.axes[axis].get_indexer_for(v)
1108+
if errors == 'raise' and len(indexer[indexer == -1]):
1109+
missing_labels = [label for index, label in enumerate(v)
1110+
if indexer[index] == -1]
1111+
raise KeyError('{} not found in axis'
1112+
.format(missing_labels))
1113+
10921114
result._data = result._data.rename_axis(f, axis=baxis, copy=copy,
10931115
level=level)
10941116
result._clear_item_cache()

pandas/core/series.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ def _set_value(self, label, value, takeable=False):
12291229
self._values[label] = value
12301230
else:
12311231
self.index._engine.set_value(self._values, label, value)
1232-
except KeyError:
1232+
except (KeyError, TypeError):
12331233

12341234
# set using a non-recursive method
12351235
self.loc[label] = value
@@ -3098,8 +3098,10 @@ def nlargest(self, n=5, keep='first'):
30983098
When there are duplicate values that cannot all fit in a
30993099
Series of `n` elements:
31003100
3101-
- ``first`` : take the first occurrences based on the index order
3102-
- ``last`` : take the last occurrences based on the index order
3101+
- ``first`` : return the first `n` occurrences in order
3102+
of appearance.
3103+
- ``last`` : return the last `n` occurrences in reverse
3104+
order of appearance.
31033105
- ``all`` : keep all occurrences. This can result in a Series of
31043106
size larger than `n`.
31053107
@@ -3194,8 +3196,10 @@ def nsmallest(self, n=5, keep='first'):
31943196
When there are duplicate values that cannot all fit in a
31953197
Series of `n` elements:
31963198
3197-
- ``first`` : take the first occurrences based on the index order
3198-
- ``last`` : take the last occurrences based on the index order
3199+
- ``first`` : return the first `n` occurrences in order
3200+
of appearance.
3201+
- ``last`` : return the last `n` occurrences in reverse
3202+
order of appearance.
31993203
- ``all`` : keep all occurrences. This can result in a Series of
32003204
size larger than `n`.
32013205
@@ -3236,7 +3240,7 @@ def nsmallest(self, n=5, keep='first'):
32363240
Monserat 5200
32373241
dtype: int64
32383242
3239-
The `n` largest elements where ``n=5`` by default.
3243+
The `n` smallest elements where ``n=5`` by default.
32403244
32413245
>>> s.nsmallest()
32423246
Monserat 5200

pandas/tests/frame/test_alter_axes.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,23 @@ def test_rename_bug2(self):
872872
columns=["a"])
873873
tm.assert_frame_equal(df, expected)
874874

875+
def test_rename_errors_raises(self):
876+
df = DataFrame(columns=['A', 'B', 'C', 'D'])
877+
with pytest.raises(KeyError, match='\'E\'] not found in axis'):
878+
df.rename(columns={'A': 'a', 'E': 'e'}, errors='raise')
879+
880+
@pytest.mark.parametrize('mapper, errors, expected_columns', [
881+
({'A': 'a', 'E': 'e'}, 'ignore', ['a', 'B', 'C', 'D']),
882+
({'A': 'a'}, 'raise', ['a', 'B', 'C', 'D']),
883+
(str.lower, 'raise', ['a', 'b', 'c', 'd'])])
884+
def test_rename_errors(self, mapper, errors, expected_columns):
885+
# GH 13473
886+
# rename now works with errors parameter
887+
df = DataFrame(columns=['A', 'B', 'C', 'D'])
888+
result = df.rename(columns=mapper, errors=errors)
889+
expected = DataFrame(columns=expected_columns)
890+
tm.assert_frame_equal(result, expected)
891+
875892
def test_reorder_levels(self):
876893
index = MultiIndex(levels=[['bar'], ['one', 'two', 'three'], [0, 1]],
877894
codes=[[0, 0, 0, 0, 0, 0],
@@ -1329,7 +1346,7 @@ def test_rename_signature(self):
13291346
sig = inspect.signature(DataFrame.rename)
13301347
parameters = set(sig.parameters)
13311348
assert parameters == {"self", "mapper", "index", "columns", "axis",
1332-
"inplace", "copy", "level"}
1349+
"inplace", "copy", "level", "errors"}
13331350

13341351
@pytest.mark.skipif(PY2, reason="inspect.signature")
13351352
def test_reindex_signature(self):

pandas/tests/indexes/interval/test_interval_tree.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ def test_is_overlapping_trivial(self, closed, left, right):
172172
tree = IntervalTree(left, right, closed=closed)
173173
assert tree.is_overlapping is False
174174

175+
@pytest.mark.skipif(compat.is_platform_32bit(), reason='GH 23440')
175176
def test_construction_overflow(self):
176177
# GH 25485
177178
left, right = np.arange(101), [np.iinfo(np.int64).max] * 101

0 commit comments

Comments
 (0)