Skip to content

Commit dc79424

Browse files
committed
Merge branch 'master' of https://github.com/pandas-dev/pandas into libmore
2 parents 79137e3 + 7191af9 commit dc79424

File tree

199 files changed

+1302
-775
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

199 files changed

+1302
-775
lines changed

doc/source/advanced.rst

+41
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,47 @@ method, allowing you to permute the hierarchical index levels in one step:
503503
504504
df[:5].reorder_levels([1,0], axis=0)
505505
506+
.. _advanced.index_names:
507+
508+
Renaming names of an ``Index`` or ``MultiIndex``
509+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
510+
511+
The :meth:`~DataFrame.rename` method is used to rename the labels of a
512+
``MultiIndex``, and is typically used to rename the columns of a ``DataFrame``.
513+
The ``columns`` argument of ``rename`` allows a dictionary to be specified
514+
that includes only the columns you wish to rename.
515+
516+
.. ipython:: python
517+
518+
df.rename(columns={0: "col0", 1: "col1"})
519+
520+
This method can also be used to rename specific labels of the main index
521+
of the ``DataFrame``.
522+
523+
.. ipython:: python
524+
525+
df.rename(index={"one" : "two", "y" : "z"})
526+
527+
The :meth:`~DataFrame.rename_axis` method is used to rename the name of a
528+
``Index`` or ``MultiIndex``. In particular, the names of the levels of a
529+
``MultiIndex`` can be specified, which is useful if ``reset_index()`` is later
530+
used to move the values from the ``MultiIndex`` to a column.
531+
532+
.. ipython:: python
533+
534+
df.rename_axis(index=['abc', 'def'])
535+
536+
Note that the columns of a ``DataFrame`` are an index, so that using
537+
``rename_axis`` with the ``columns`` argument will change the name of that
538+
index.
539+
540+
.. ipython:: python
541+
542+
df.rename_axis(columns="Cols").columns
543+
544+
Both ``rename`` and ``rename_axis`` support specifying a dictionary,
545+
``Series`` or a mapping function to map labels/names to new values.
546+
506547
Sorting a ``MultiIndex``
507548
------------------------
508549

doc/source/basics.rst

+15-2
Original file line numberDiff line numberDiff line change
@@ -1466,8 +1466,21 @@ for altering the ``Series.name`` attribute.
14661466
14671467
.. _basics.rename_axis:
14681468

1469-
The Panel class has a related :meth:`~Panel.rename_axis` class which can rename
1470-
any of its three axes.
1469+
.. versionadded:: 0.24.0
1470+
1471+
The methods :meth:`~DataFrame.rename_axis` and :meth:`~Series.rename_axis`
1472+
allow specific names of a `MultiIndex` to be changed (as opposed to the
1473+
labels).
1474+
1475+
.. ipython:: python
1476+
1477+
df = pd.DataFrame({'x': [1, 2, 3, 4, 5, 6],
1478+
'y': [10, 20, 30, 40, 50, 60]},
1479+
index=pd.MultiIndex.from_product([['a', 'b', 'c'], [1, 2]],
1480+
names=['let', 'num']))
1481+
df
1482+
df.rename_axis(index={'let': 'abc'})
1483+
df.rename_axis(index=str.upper)
14711484
14721485
.. _basics.iteration:
14731486

doc/source/whatsnew/v0.24.0.txt

+27-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,29 @@ array, but rather an ``ExtensionArray``:
180180
This is the same behavior as ``Series.values`` for categorical data. See
181181
:ref:`whatsnew_0240.api_breaking.interval_values` for more.
182182

183+
.. _whatsnew_0240.enhancements.rename_axis:
184+
185+
Renaming names in a MultiIndex
186+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
187+
188+
:func:`DataFrame.rename_axis` now supports ``index`` and ``columns`` arguments
189+
and :func:`Series.rename_axis` supports ``index`` argument (:issue:`19978`)
190+
191+
This change allows a dictionary to be passed so that some of the names
192+
of a ``MultiIndex`` can be changed.
193+
194+
Example:
195+
196+
.. ipython:: python
197+
198+
mi = pd.MultiIndex.from_product([list('AB'), list('CD'), list('EF')],
199+
names=['AB', 'CD', 'EF'])
200+
df = pd.DataFrame([i for i in range(len(mi))], index=mi, columns=['N'])
201+
df
202+
df.rename_axis(index={'CD': 'New'})
203+
204+
See the :ref:`advanced docs on renaming<advanced.index_names>` for more details.
205+
183206
.. _whatsnew_0240.enhancements.other:
184207

185208
Other Enhancements
@@ -930,6 +953,7 @@ Deprecations
930953
- :func:`DatetimeIndex.shift` and :func:`PeriodIndex.shift` now accept ``periods`` argument instead of ``n`` for consistency with :func:`Index.shift` and :func:`Series.shift`. Using ``n`` throws a deprecation warning (:issue:`22458`, :issue:`22912`)
931954
- The ``fastpath`` keyword of the different Index constructors is deprecated (:issue:`23110`).
932955
- :meth:`Timestamp.tz_localize`, :meth:`DatetimeIndex.tz_localize`, and :meth:`Series.tz_localize` have deprecated the ``errors`` argument in favor of the ``nonexistent`` argument (:issue:`8917`)
956+
- The class ``FrozenNDArray`` has been deprecated. When unpickling, ``FrozenNDArray`` will be unpickled to ``np.ndarray`` once this class is removed (:issue:`9031`)
933957

934958
.. _whatsnew_0240.prior_deprecations:
935959

@@ -942,7 +966,7 @@ Removal of prior version deprecations/changes
942966
- Removal of the previously deprecated module ``pandas.core.datetools`` (:issue:`14105`, :issue:`14094`)
943967
- Strings passed into :meth:`DataFrame.groupby` that refer to both column and index levels will raise a ``ValueError`` (:issue:`14432`)
944968
- :meth:`Index.repeat` and :meth:`MultiIndex.repeat` have renamed the ``n`` argument to ``repeats`` (:issue:`14645`)
945-
- The ``Series`` constructor and ``.astype`` method will now raise a ``ValueError`` if timestamp dtypes are passed in without a frequency (e.g. ``np.datetime64``) for the ``dtype`` parameter (:issue:`15987`)
969+
- The ``Series`` constructor and ``.astype`` method will now raise a ``ValueError`` if timestamp dtypes are passed in without a unit (e.g. ``np.datetime64``) for the ``dtype`` parameter (:issue:`15987`)
946970
- Removal of the previously deprecated ``as_indexer`` keyword completely from ``str.match()`` (:issue:`22356`, :issue:`6581`)
947971
- The modules ``pandas.types``, ``pandas.computation``, and ``pandas.util.decorators`` have been removed (:issue:`16157`, :issue:`16250`)
948972
- Removed the ``pandas.formats.style`` shim for :class:`pandas.io.formats.style.Styler` (:issue:`16059`)
@@ -1030,6 +1054,7 @@ Datetimelike
10301054
- Bug in :func:`to_datetime` with an :class:`Index` argument that would drop the ``name`` from the result (:issue:`21697`)
10311055
- Bug in :class:`PeriodIndex` where adding or subtracting a :class:`timedelta` or :class:`Tick` object produced incorrect results (:issue:`22988`)
10321056
- Bug in :func:`date_range` when decrementing a start date to a past end date by a negative frequency (:issue:`23270`)
1057+
- Bug in :meth:`Series.min` which would return ``NaN`` instead of ``NaT`` when called on a series of ``NaT`` (:issue:`23282`)
10331058
- Bug in :func:`DataFrame.combine` with datetimelike values raising a TypeError (:issue:`23079`)
10341059
- Bug in :func:`date_range` with frequency of ``Day`` or higher where dates sufficiently far in the future could wrap around to the past instead of raising ``OutOfBoundsDatetime`` (:issue:`14187`)
10351060
- Bug in :class:`PeriodIndex` with attribute ``freq.n`` greater than 1 where adding a :class:`DateOffset` object would return incorrect results (:issue:`23215`)
@@ -1108,6 +1133,7 @@ Interval
11081133
- Bug in the ``IntervalIndex`` repr where a trailing comma was missing after the list of intervals (:issue:`20611`)
11091134
- Bug in :class:`Interval` where scalar arithmetic operations did not retain the ``closed`` value (:issue:`22313`)
11101135
- Bug in :class:`IntervalIndex` where indexing with datetime-like values raised a ``KeyError`` (:issue:`20636`)
1136+
- Bug in ``IntervalTree`` where data containing ``NaN`` triggered a warning and resulted in incorrect indexing queries with :class:`IntervalIndex` (:issue:`23352`)
11111137

11121138
Indexing
11131139
^^^^^^^^

pandas/_libs/intervaltree.pxi.in

+6
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ cdef class IntervalTree(IntervalMixin):
7272

7373
self.closed = closed
7474

75+
# GH 23352: ensure no nan in nodes
76+
mask = ~np.isnan(self.left)
77+
self.left = self.left[mask]
78+
self.right = self.right[mask]
79+
indices = indices[mask]
80+
7581
node_cls = NODE_CLASSES[str(self.dtype), closed]
7682
self.root = node_cls(self.left, self.right, indices, leaf_size)
7783

pandas/_version.py

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import re
1313
import subprocess
1414
import sys
15+
1516
from pandas.compat import PY3
1617

1718

pandas/compat/pickle_compat.py

+11
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ def load_reduce(self):
6060
('pandas.core.arrays', 'SparseArray'),
6161

6262
# 15477
63+
#
64+
# TODO: When FrozenNDArray is removed, add
65+
# the following lines for compat:
66+
#
67+
# ('pandas.core.base', 'FrozenNDArray'):
68+
# ('numpy', 'ndarray'),
69+
# ('pandas.core.indexes.frozen', 'FrozenNDArray'):
70+
# ('numpy', 'ndarray'),
71+
#
72+
# Afterwards, remove the current entry
73+
# for `pandas.core.base.FrozenNDArray`.
6374
('pandas.core.base', 'FrozenNDArray'):
6475
('pandas.core.indexes.frozen', 'FrozenNDArray'),
6576
('pandas.core.base', 'FrozenList'):

pandas/conftest.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import os
21
import importlib
2+
import os
33

4+
import hypothesis
5+
from hypothesis import strategies as st
6+
import numpy as np
47
import pytest
58

6-
import pandas
7-
import numpy as np
8-
import pandas as pd
99
from pandas.compat import PY3
1010
import pandas.util._test_decorators as td
11-
import hypothesis
1211

12+
import pandas as pd
1313

1414
hypothesis.settings.register_profile(
1515
"ci",
@@ -285,7 +285,7 @@ def deco(*args):
285285
@pytest.fixture
286286
def iris(datapath):
287287
"""The iris dataset as a DataFrame."""
288-
return pandas.read_csv(datapath('data', 'iris.csv'))
288+
return pd.read_csv(datapath('data', 'iris.csv'))
289289

290290

291291
@pytest.fixture(params=['nlargest', 'nsmallest'])
@@ -512,7 +512,6 @@ def mock():
512512
# ----------------------------------------------------------------
513513
# Global setup for tests using Hypothesis
514514

515-
from hypothesis import strategies as st
516515

517516
# Registering these strategies makes them globally available via st.from_type,
518517
# which is use for offsets in tests/tseries/offsets/test_offsets_properties.py

pandas/core/arrays/sparse.py

+15-15
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,35 @@
1010

1111
import numpy as np
1212

13-
import pandas._libs.sparse as splib
14-
import pandas.core.algorithms as algos
15-
import pandas.core.common as com
16-
import pandas.io.formats.printing as printing
17-
from pandas import compat
1813
from pandas._libs import index as libindex, lib
14+
import pandas._libs.sparse as splib
1915
from pandas._libs.sparse import BlockIndex, IntIndex
2016
from pandas._libs.tslibs import NaT
17+
import pandas.compat as compat
2118
from pandas.compat.numpy import function as nv
22-
from pandas.core.accessor import PandasDelegate, delegate_names
23-
from pandas.core.arrays import ExtensionArray, ExtensionOpsMixin
24-
from pandas.core.base import PandasObject
19+
from pandas.errors import PerformanceWarning
20+
2521
from pandas.core.dtypes.base import ExtensionDtype
2622
from pandas.core.dtypes.cast import (
2723
astype_nansafe, construct_1d_arraylike_from_scalar, find_common_type,
28-
infer_dtype_from_scalar, maybe_convert_platform
29-
)
24+
infer_dtype_from_scalar, maybe_convert_platform)
3025
from pandas.core.dtypes.common import (
3126
is_array_like, is_bool_dtype, is_datetime64_any_dtype, is_dtype_equal,
3227
is_integer, is_list_like, is_object_dtype, is_scalar, is_string_dtype,
33-
pandas_dtype
34-
)
28+
pandas_dtype)
3529
from pandas.core.dtypes.dtypes import register_extension_dtype
3630
from pandas.core.dtypes.generic import (
37-
ABCIndexClass, ABCSeries, ABCSparseSeries
38-
)
31+
ABCIndexClass, ABCSeries, ABCSparseSeries)
3932
from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna
33+
34+
from pandas.core.accessor import PandasDelegate, delegate_names
35+
import pandas.core.algorithms as algos
36+
from pandas.core.arrays import ExtensionArray, ExtensionOpsMixin
37+
from pandas.core.base import PandasObject
38+
import pandas.core.common as com
4039
from pandas.core.missing import interpolate_2d
41-
from pandas.errors import PerformanceWarning
40+
41+
import pandas.io.formats.printing as printing
4242

4343

4444
# ----------------------------------------------------------------------------

pandas/core/common.py

+18
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,21 @@ def _pipe(obj, func, *args, **kwargs):
454454
return func(*args, **kwargs)
455455
else:
456456
return func(obj, *args, **kwargs)
457+
458+
459+
def _get_rename_function(mapper):
460+
"""
461+
Returns a function that will map names/labels, dependent if mapper
462+
is a dict, Series or just a function.
463+
"""
464+
if isinstance(mapper, (compat.Mapping, ABCSeries)):
465+
466+
def f(x):
467+
if x in mapper:
468+
return mapper[x]
469+
else:
470+
return x
471+
else:
472+
f = mapper
473+
474+
return f

pandas/core/dtypes/cast.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ def astype_nansafe(arr, dtype, copy=True, skipna=False):
667667
Raises
668668
------
669669
ValueError
670-
The dtype was a datetime /timedelta dtype, but it had no frequency.
670+
The dtype was a datetime64/timedelta64 dtype, but it had no unit.
671671
"""
672672

673673
# dispatch on extension dtype if needed
@@ -749,7 +749,7 @@ def astype_nansafe(arr, dtype, copy=True, skipna=False):
749749
return astype_nansafe(to_timedelta(arr).values, dtype, copy=copy)
750750

751751
if dtype.name in ("datetime64", "timedelta64"):
752-
msg = ("The '{dtype}' dtype has no frequency. "
752+
msg = ("The '{dtype}' dtype has no unit. "
753753
"Please pass in '{dtype}[ns]' instead.")
754754
raise ValueError(msg.format(dtype=dtype.name))
755755

@@ -1021,7 +1021,7 @@ def maybe_cast_to_datetime(value, dtype, errors='raise'):
10211021
if is_datetime64 or is_datetime64tz or is_timedelta64:
10221022

10231023
# Force the dtype if needed.
1024-
msg = ("The '{dtype}' dtype has no frequency. "
1024+
msg = ("The '{dtype}' dtype has no unit. "
10251025
"Please pass in '{dtype}[ns]' instead.")
10261026

10271027
if is_datetime64 and not is_dtype_equal(dtype, _NS_DTYPE):

pandas/core/frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4944,7 +4944,7 @@ def _combine_match_columns(self, other, func, level=None):
49444944
assert left.columns.equals(right.index)
49454945
return ops.dispatch_to_series(left, right, func, axis="columns")
49464946

4947-
def _combine_const(self, other, func, errors='raise'):
4947+
def _combine_const(self, other, func):
49484948
assert lib.is_scalar(other) or np.ndim(other) == 0
49494949
return ops.dispatch_to_series(self, other, func)
49504950

0 commit comments

Comments
 (0)