Skip to content

Commit 717dd68

Browse files
committed
Merge remote-tracking branch 'upstream' into fix/issue-1918-bar-plot-dateformatter
2 parents 9d3ba2f + 1a3230d commit 717dd68

File tree

228 files changed

+3145
-1754
lines changed

Some content is hidden

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

228 files changed

+3145
-1754
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ci:
1919
skip: [pyright, mypy]
2020
repos:
2121
- repo: https://github.com/astral-sh/ruff-pre-commit
22-
rev: v0.14.3
22+
rev: v0.14.7
2323
hooks:
2424
- id: ruff
2525
args: [--exit-non-zero-on-fix]
@@ -71,7 +71,7 @@ repos:
7171
hooks:
7272
- id: isort
7373
- repo: https://github.com/asottile/pyupgrade
74-
rev: v3.21.0
74+
rev: v3.21.2
7575
hooks:
7676
- id: pyupgrade
7777
args: [--py311-plus]
@@ -87,12 +87,12 @@ repos:
8787
types: [text] # overwrite types: [rst]
8888
types_or: [python, rst]
8989
- repo: https://github.com/sphinx-contrib/sphinx-lint
90-
rev: v1.0.1
90+
rev: v1.0.2
9191
hooks:
9292
- id: sphinx-lint
9393
args: ["--enable", "all", "--disable", "line-too-long"]
9494
- repo: https://github.com/pre-commit/mirrors-clang-format
95-
rev: v21.1.2
95+
rev: v21.1.6
9696
hooks:
9797
- id: clang-format
9898
files: ^pandas/_libs/src|^pandas/_libs/include

ci/code_checks.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then
7272
-i "pandas.Series.dt PR01" `# Accessors are implemented as classes, but we do not document the Parameters section` \
7373
-i "pandas.Period.freq GL08" \
7474
-i "pandas.Period.ordinal GL08" \
75+
-i "pandas.errors.ChainedAssignmentError SA01" \
7576
-i "pandas.errors.IncompatibleFrequency SA01,SS06,EX01" \
7677
-i "pandas.api.extensions.ExtensionArray.value_counts EX01,RT03,SA01" \
7778
-i "pandas.api.typing.DataFrameGroupBy.plot PR02" \

doc/source/whatsnew/v3.0.0.rst

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ process in more detail.
117117

118118
`PDEP-7: Consistent copy/view semantics in pandas with Copy-on-Write <https://pandas.pydata.org/pdeps/0007-copy-on-write.html>`__
119119

120+
Setting the option ``mode.copy_on_write`` no longer has any impact. The option is deprecated
121+
and will be removed in pandas 4.0.
122+
120123
.. _whatsnew_300.enhancements.col:
121124

122125
``pd.col`` syntax can now be used in :meth:`DataFrame.assign` and :meth:`DataFrame.loc`
@@ -382,6 +385,8 @@ In cases with mixed-resolution inputs, the highest resolution is used:
382385
383386
.. warning:: Many users will now get "M8[us]" dtype data in cases when they used to get "M8[ns]". For most use cases they should not notice a difference. One big exception is converting to integers, which will give integers 1000x smaller.
384387

388+
Similarly, the :class:`Timedelta` constructor and :func:`to_timedelta` with a string input now defaults to a microsecond unit, using nanosecond unit only in cases that actually have nanosecond precision.
389+
385390
.. _whatsnew_300.api_breaking.concat_datetime_sorting:
386391

387392
:func:`concat` no longer ignores ``sort`` when all objects have a :class:`DatetimeIndex`
@@ -548,29 +553,55 @@ small behavior differences as collateral:
548553
Changed treatment of NaN values in pyarrow and numpy-nullable floating dtypes
549554
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
550555

551-
Previously, when dealing with a nullable dtype (e.g. ``Float64Dtype`` or ``int64[pyarrow]``), ``NaN`` was treated as interchangeable with :class:`NA` in some circumstances but not others. This was done to make adoption easier, but caused some confusion (:issue:`32265`). In 3.0, an option ``"mode.nan_is_na"`` (default ``True``) controls whether to treat ``NaN`` as equivalent to :class:`NA`.
556+
Previously, when dealing with a nullable dtype (e.g. ``Float64Dtype`` or ``int64[pyarrow]``),
557+
``NaN`` was treated as interchangeable with :class:`NA` in some circumstances but not others.
558+
This was done to make adoption easier, but caused some confusion (:issue:`32265`).
559+
In 3.0, this behaviour is made consistent to by default treat ``NaN`` as equivalent
560+
to :class:`NA` in all cases.
552561

553-
With ``pd.set_option("mode.nan_is_na", True)`` (again, this is the default), ``NaN`` can be passed to constructors, ``__setitem__``, ``__contains__`` and be treated the same as :class:`NA`. The only change users will see is that arithmetic and ``np.ufunc`` operations that previously introduced ``NaN`` entries produce :class:`NA` entries instead:
562+
By default, ``NaN`` can be passed to constructors, ``__setitem__``, ``__contains__``
563+
and will be treated the same as :class:`NA`. The only change users will see is
564+
that arithmetic and ``np.ufunc`` operations that previously introduced ``NaN``
565+
entries produce :class:`NA` entries instead.
554566

555567
*Old behavior:*
556568

557569
.. code-block:: ipython
558570
559-
In [2]: ser = pd.Series([0, None], dtype=pd.Float64Dtype())
571+
# NaN in input gets converted to NA
572+
In [1]: ser = pd.Series([0, np.nan], dtype=pd.Float64Dtype())
573+
In [2]: ser
574+
Out[2]:
575+
0 0.0
576+
1 <NA>
577+
dtype: Float64
578+
# NaN produced by arithmetic (0/0) remained NaN
560579
In [3]: ser / 0
561580
Out[3]:
562581
0 NaN
563582
1 <NA>
564583
dtype: Float64
584+
# the NaN value is not considered as missing
585+
In [4]: (ser / 0).isna()
586+
Out[4]:
587+
0 False
588+
1 True
589+
dtype: bool
565590
566591
*New behavior:*
567592

568593
.. ipython:: python
569594
570-
ser = pd.Series([0, None], dtype=pd.Float64Dtype())
595+
ser = pd.Series([0, np.nan], dtype=pd.Float64Dtype())
596+
ser
571597
ser / 0
598+
(ser / 0).isna()
572599
573-
By contrast, with ``pd.set_option("mode.nan_is_na", False)``, ``NaN`` is always considered distinct and specifically as a floating-point value, so cannot be used with integer dtypes:
600+
In the future, the intention is to consider ``NaN`` and :class:`NA` as distinct
601+
values, and an option to control this behaviour is added in 3.0 through
602+
``pd.options.future.distinguish_nan_and_na``. When enabled, ``NaN`` is always
603+
considered distinct and specifically as a floating-point value. As a consequence,
604+
it cannot be used with integer dtypes.
574605

575606
*Old behavior:*
576607

@@ -584,13 +615,21 @@ By contrast, with ``pd.set_option("mode.nan_is_na", False)``, ``NaN`` is always
584615

585616
.. ipython:: python
586617
587-
pd.set_option("mode.nan_is_na", False)
588-
ser = pd.Series([1, np.nan], dtype=pd.Float64Dtype())
589-
ser[1]
618+
with pd.option_context("future.distinguish_nan_and_na", True):
619+
ser = pd.Series([1, np.nan], dtype=pd.Float64Dtype())
620+
print(ser[1])
621+
622+
If we had passed ``pd.Int64Dtype()`` or ``"int64[pyarrow]"`` for the dtype in
623+
the latter example, this would raise, as a float ``NaN`` cannot be held by an
624+
integer dtype.
590625

591-
If we had passed ``pd.Int64Dtype()`` or ``"int64[pyarrow]"`` for the dtype in the latter example, this would raise, as a float ``NaN`` cannot be held by an integer dtype.
626+
With ``"future.distinguish_nan_and_na"`` enabled, ``ser.to_numpy()`` (and
627+
``frame.values`` and ``np.asarray(obj)``) will convert to ``object`` dtype if
628+
:class:`NA` entries are present, where before they would coerce to
629+
``NaN``. To retain a float numpy dtype, explicitly pass ``na_value=np.nan``
630+
to :meth:`Series.to_numpy`.
592631

593-
With ``"mode.nan_is_na"`` set to ``False``, ``ser.to_numpy()`` (and ``frame.values`` and ``np.asarray(obj)``) will convert to ``object`` dtype if :class:`NA` entries are present, where before they would coerce to ``NaN``. To retain a float numpy dtype, explicitly pass ``na_value=np.nan`` to :meth:`Series.to_numpy`.
632+
Note that the option is experimental and subject to change in future releases.
594633

595634
The ``__module__`` attribute now points to public modules
596635
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -749,11 +788,16 @@ Other API changes
749788
the dtype of the resulting Index (:issue:`60797`)
750789
- :class:`IncompatibleFrequency` now subclasses ``TypeError`` instead of ``ValueError``. As a result, joins with mismatched frequencies now cast to object like other non-comparable joins, and arithmetic with indexes with mismatched frequencies align (:issue:`55782`)
751790
- :class:`Series` "flex" methods like :meth:`Series.add` no longer allow passing a :class:`DataFrame` for ``other``; use the DataFrame reversed method instead (:issue:`46179`)
791+
- :func:`date_range` and :func:`timedelta_range` no longer default to ``unit="ns"``, instead will infer a unit from the ``start``, ``end``, and ``freq`` parameters. Explicitly specify a desired ``unit`` to override these (:issue:`59031`)
752792
- :meth:`CategoricalIndex.append` no longer attempts to cast different-dtype indexes to the caller's dtype (:issue:`41626`)
753793
- :meth:`ExtensionDtype.construct_array_type` is now a regular method instead of a ``classmethod`` (:issue:`58663`)
754794
- Arithmetic operations between a :class:`Series`, :class:`Index`, or :class:`ExtensionArray` with a ``list`` now consistently wrap that list with an array equivalent to ``Series(my_list).array``. To do any other kind of type inference or casting, do so explicitly before operating (:issue:`62552`)
755795
- Comparison operations between :class:`Index` and :class:`Series` now consistently return :class:`Series` regardless of which object is on the left or right (:issue:`36759`)
756796
- Numpy functions like ``np.isinf`` that return a bool dtype when called on a :class:`Index` object now return a bool-dtype :class:`Index` instead of ``np.ndarray`` (:issue:`52676`)
797+
- Methods that can operate in-place (:meth:`~DataFrame.replace`, :meth:`~DataFrame.fillna`,
798+
:meth:`~DataFrame.ffill`, :meth:`~DataFrame.bfill`, :meth:`~DataFrame.interpolate`,
799+
:meth:`~DataFrame.where`, :meth:`~DataFrame.mask`, :meth:`~DataFrame.clip`) now return
800+
the modified DataFrame or Series (``self``) instead of ``None`` when ``inplace=True`` (:issue:`63207`)
757801

758802
.. ---------------------------------------------------------------------------
759803
.. _whatsnew_300.deprecations:
@@ -1183,9 +1227,11 @@ MultiIndex
11831227
I/O
11841228
^^^
11851229
- Bug in :class:`DataFrame` and :class:`Series` ``repr`` of :py:class:`collections.abc.Mapping` elements. (:issue:`57915`)
1230+
- Bug in :meth:`DataFrame.to_hdf` and :func:`read_hdf` with ``timedelta64`` dtypes with non-nanosecond resolution failing to round-trip correctly (:issue:`63239`)
11861231
- Fix bug in ``on_bad_lines`` callable when returning too many fields: now emits
11871232
``ParserWarning`` and truncates extra fields regardless of ``index_col`` (:issue:`61837`)
11881233
- Bug in :func:`pandas.json_normalize` inconsistently handling non-dict items in ``data`` when ``max_level`` was set. The function will now raise a ``TypeError`` if ``data`` is a list containing non-dict items (:issue:`62829`)
1234+
- Bug in :func:`pandas.json_normalize` raising ``TypeError`` when ``meta`` contained a non-string key (e.g., ``int``) and ``record_path`` was specified, which was inconsistent with the behavior when ``record_path`` was ``None`` (:issue:`63019`)
11891235
- Bug in :meth:`.DataFrame.to_json` when ``"index"`` was a value in the :attr:`DataFrame.column` and :attr:`Index.name` was ``None``. Now, this will fail with a ``ValueError`` (:issue:`58925`)
11901236
- Bug in :meth:`.io.common.is_fsspec_url` not recognizing chained fsspec URLs (:issue:`48978`)
11911237
- Bug in :meth:`DataFrame._repr_html_` which ignored the ``"display.float_format"`` option (:issue:`59876`)
@@ -1239,6 +1285,7 @@ Plotting
12391285
- Bug in :meth:`Series.plot` preventing a line and bar from being aligned on the same plot (:issue:`61161`)
12401286
- Bug in :meth:`Series.plot` preventing a line and scatter plot from being aligned (:issue:`61005`)
12411287
- Bug in :meth:`Series.plot` with ``kind="pie"`` with :class:`ArrowDtype` (:issue:`59192`)
1288+
- Bug in plotting with a :class:`TimedeltaIndex` with non-nanosecond resolution displaying incorrect labels (:issue:`63237`)
12421289

12431290
Groupby/resample/rolling
12441291
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1269,7 +1316,8 @@ Groupby/resample/rolling
12691316
- Bug in :meth:`Rolling.apply` for ``method="table"`` where column order was not being respected due to the columns getting sorted by default. (:issue:`59666`)
12701317
- Bug in :meth:`Rolling.apply` where the applied function could be called on fewer than ``min_period`` periods if ``method="table"``. (:issue:`58868`)
12711318
- Bug in :meth:`Rolling.sem` computing incorrect results because it divided by ``sqrt((n - 1) * (n - ddof))`` instead of ``sqrt(n * (n - ddof))``. (:issue:`63180`)
1272-
- Bug in :meth:`Rolling.skew` incorrectly computing skewness for windows following outliers due to numerical instability. The calculation now properly handles catastrophic cancellation by recomputing affected windows (:issue:`47461`)
1319+
- Bug in :meth:`Rolling.skew` and in :meth:`Rolling.kurt` incorrectly computing skewness and kurtosis, respectively, for windows following outliers due to numerical instability. The calculation now properly handles catastrophic cancellation by recomputing affected windows (:issue:`47461`, :issue:`61416`)
1320+
- Bug in :meth:`Rolling.skew` and in :meth:`Rolling.kurt` where results varied with input length despite identical data and window contents (:issue:`54380`)
12731321
- Bug in :meth:`Series.resample` could raise when the date range ended shortly before a non-existent time. (:issue:`58380`)
12741322
- Bug in :meth:`Series.resample` raising error when resampling non-nanosecond resolutions out of bounds for nanosecond precision (:issue:`57427`)
12751323
- Bug in :meth:`Series.rolling.var` and :meth:`Series.rolling.std` computing incorrect results due to numerical instability. (:issue:`47721`, :issue:`52407`, :issue:`54518`, :issue:`55343`)
@@ -1307,6 +1355,7 @@ Sparse
13071355
- Bug in :class:`SparseDtype` for equal comparison with na fill value. (:issue:`54770`)
13081356
- Bug in :meth:`DataFrame.sparse.from_spmatrix` which hard coded an invalid ``fill_value`` for certain subtypes. (:issue:`59063`)
13091357
- Bug in :meth:`DataFrame.sparse.to_dense` which ignored subclassing and always returned an instance of :class:`DataFrame` (:issue:`59913`)
1358+
- Bug in :meth:`cumsum` for integer arrays Calling SparseArray.cumsum caused max recursion depth error. (:issue:`62669`)
13101359

13111360
ExtensionArray
13121361
^^^^^^^^^^^^^^

pandas/_config/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ def using_string_dtype() -> bool:
3636

3737

3838
def is_nan_na() -> bool:
39-
_mode_options = _global_config["mode"]
40-
return _mode_options["nan_is_na"]
39+
_mode_options = _global_config["future"]
40+
return not _mode_options["distinguish_nan_and_na"]

pandas/_libs/hashtable_class_helper.pxi.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ cdef class StringHashTable(HashTable):
10701070
val = values[i]
10711071

10721072
if isinstance(val, str):
1073-
# GH#31499 if we have a np.str_ PyUnicode_AsUTF8 won't recognize
1073+
# GH#31499 if we have an np.str_ PyUnicode_AsUTF8 won't recognize
10741074
# it as a str, even though isinstance does.
10751075
v = PyUnicode_AsUTF8(<str>val)
10761076
else:
@@ -1108,7 +1108,7 @@ cdef class StringHashTable(HashTable):
11081108
val = values[i]
11091109

11101110
if isinstance(val, str):
1111-
# GH#31499 if we have a np.str_ PyUnicode_AsUTF8 won't recognize
1111+
# GH#31499 if we have an np.str_ PyUnicode_AsUTF8 won't recognize
11121112
# it as a str, even though isinstance does.
11131113
v = PyUnicode_AsUTF8(<str>val)
11141114
else:

pandas/_libs/index.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ cdef bint is_definitely_invalid_key(object val):
5858

5959
cdef ndarray _get_bool_indexer(ndarray values, object val, ndarray mask = None):
6060
"""
61-
Return a ndarray[bool] of locations where val matches self.values.
61+
Return an ndarray[bool] of locations where val matches self.values.
6262
6363
If val is not NA, this is equivalent to `self.values == val`
6464
"""

pandas/_libs/lib.pyx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ from pandas._libs.tslibs.nattype cimport (
106106
)
107107
from pandas._libs.tslibs.offsets cimport is_offset_object
108108
from pandas._libs.tslibs.period cimport is_period_object
109-
from pandas._libs.tslibs.timedeltas cimport convert_to_timedelta64
110109
from pandas._libs.tslibs.timezones cimport tz_compare
111110

112111
# constants that will be compared to potentially arbitrarily large
@@ -2674,11 +2673,6 @@ def maybe_convert_objects(ndarray[object] objects,
26742673
elif is_timedelta(val):
26752674
if convert_non_numeric:
26762675
seen.timedelta_ = True
2677-
try:
2678-
convert_to_timedelta64(val, "ns")
2679-
except OutOfBoundsTimedelta:
2680-
seen.object_ = True
2681-
break
26822676
break
26832677
else:
26842678
seen.object_ = True

pandas/_libs/tslib.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def format_array_from_datetime(
120120
NPY_DATETIMEUNIT reso=NPY_FR_ns,
121121
) -> np.ndarray:
122122
"""
123-
return a np object array of the string formatted values
123+
return an np object array of the string formatted values
124124

125125
Parameters
126126
----------

pandas/_libs/tslibs/conversion.pxd

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ cdef int64_t get_datetime64_nanos(object val, NPY_DATETIMEUNIT reso) except? -1
4545

4646
cpdef datetime localize_pydatetime(datetime dt, tzinfo tz)
4747
cdef int64_t cast_from_unit(object ts, str unit, NPY_DATETIMEUNIT out_reso=*) except? -1
48-
cdef (int64_t, int) precision_from_unit(
49-
NPY_DATETIMEUNIT in_reso, NPY_DATETIMEUNIT out_reso=*
50-
)
5148

5249
cdef maybe_localize_tso(_TSObject obj, tzinfo tz, NPY_DATETIMEUNIT reso)
5350

pandas/_libs/tslibs/conversion.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ cdef (int64_t, int) precision_from_unit(
276276

277277
cdef int64_t get_datetime64_nanos(object val, NPY_DATETIMEUNIT reso) except? -1:
278278
"""
279-
Extract the value and unit from a np.datetime64 object, then convert the
279+
Extract the value and unit from an np.datetime64 object, then convert the
280280
value to nanoseconds if necessary.
281281
"""
282282
cdef:

0 commit comments

Comments
 (0)