These are the changes in pandas 1.4.0. See :ref:`release` for a full changelog including other versions of pandas.
{{ header }}
Until now, it has only been possible to create numeric indexes with int64/float64/uint64 dtypes. It is now possible to create an index of any numpy int/uint/float dtype using the new :class:`NumericIndex` index type (:issue:`41153`):
.. ipython:: python pd.NumericIndex([1, 2, 3], dtype="int8") pd.NumericIndex([1, 2, 3], dtype="uint32") pd.NumericIndex([1, 2, 3], dtype="float32")
In order to maintain backwards compatibility, calls to the base :class:`Index` will currently
return :class:`Int64Index`, :class:`UInt64Index` and :class:`Float64Index`, where relevant.
For example, the code below returns an Int64Index
with dtype int64
:
In [1]: pd.Index([1, 2, 3], dtype="int8")
Int64Index([1, 2, 3], dtype='int64')
but will in a future version return a :class:`NumericIndex` with dtype int8
.
More generally, currently, all operations that until now have
returned :class:`Int64Index`, :class:`UInt64Index` and :class:`Float64Index` will
continue to so. This means, that in order to use NumericIndex
in the current version, you
will have to call NumericIndex
explicitly. For example the below series will have an Int64Index
:
In [2]: ser = pd.Series([1, 2, 3], index=[1, 2, 3])
In [3]: ser.index
Int64Index([1, 2, 3], dtype='int64')
Instead, if you want to use a NumericIndex
, you should do:
.. ipython:: python idx = pd.NumericIndex([1, 2, 3], dtype="int8") ser = pd.Series([1, 2, 3], index=idx) ser.index
In a future version of Pandas, :class:`NumericIndex` will become the default numeric index type and
Int64Index
, UInt64Index
and Float64Index
are therefore deprecated and will
be removed in the future, see :ref:`here <whatsnew_140.deprecations.int64_uint64_float64index>` for more.
See :ref:`here <advanced.numericindex>` for more about :class:`NumericIndex`.
:class:`.Styler` has been further developed in 1.4.0. The following enhancements have been made:
- Styling of indexing has been added, with :meth:`.Styler.apply_index` and :meth:`.Styler.applymap_index`. These mirror the signature of the methods already used to style data values, and work with both HTML and LaTeX format (:issue:`41893`).
- :meth:`.Styler.bar` introduces additional arguments to control alignment and display (:issue:`26070`, :issue:`36419`), and it also validates the input arguments
width
andheight
(:issue:`42511`).- :meth:`.Styler.to_latex` introduces keyword argument
environment
, which also allows a specific "longtable" entry through a separate jinja2 template (:issue:`41866`).- :meth:`.Styler.to_html` introduces keyword arguments
sparse_index
,sparse_columns
,bold_headers
,caption
(:issue:`41946`, :issue:`43149`).- Keyword arguments
level
andnames
added to :meth:`.Styler.hide_index` and :meth:`.Styler.hide_columns` for additional control of visibility of MultiIndexes and index names (:issue:`25475`, :issue:`43404`, :issue:`43346`)- Global options have been extended to configure default
Styler
properties including formatting and encoding and mathjax options and LaTeX (:issue:`41395`)- Naive sparsification is now possible for LaTeX without the multirow package (:issue:`43369`)
Formerly Styler relied on display.html.use_mathjax
, which has now been replaced by styler.html.mathjax
.
There are also bug fixes and deprecations listed below.
Validation now for caption
arg (:issue:`43368`)
:func:`pandas.read_csv` now accepts engine="pyarrow"
(requires at least pyarrow
0.17.0) as an argument, allowing for faster csv parsing on multicore machines
with pyarrow installed. See the :doc:`I/O docs </user_guide/io>` for more info. (:issue:`23697`)
- :class:`DataFrameGroupBy` operations with
as_index=False
now correctly retainExtensionDtype
dtypes for columns being grouped on (:issue:`41373`) - Add support for assigning values to
by
argument in :meth:`DataFrame.plot.hist` and :meth:`DataFrame.plot.box` (:issue:`15079`) - :meth:`Series.sample`, :meth:`DataFrame.sample`, and :meth:`.GroupBy.sample` now accept a
np.random.Generator
as input torandom_state
. A generator will be more performant, especially withreplace=False
(:issue:`38100`) - :meth:`Series.ewm`, :meth:`DataFrame.ewm`, now support a
method
argument with a'table'
option that performs the windowing operation over an entire :class:`DataFrame`. See :ref:`Window Overview <window.overview>` for performance and functional benefits (:issue:`42273`) - :meth:`.GroupBy.cummin` and :meth:`.GroupBy.cummax` now support the argument
skipna
(:issue:`34047`) - :meth:`read_table` now supports the argument
storage_options
(:issue:`39167`) - Methods that relied on hashmap based algos such as :meth:`DataFrameGroupBy.value_counts`, :meth:`DataFrameGroupBy.count` and :func:`factorize` ignored imaginary component for complex numbers (:issue:`17927`)
- Add :meth:`Series.str.removeprefix` and :meth:`Series.str.removesuffix` introduced in Python 3.9 to remove pre-/suffixes from string-type :class:`Series` (:issue:`36944`)
These are bug fixes that might have notable behavior changes.
The dayfirst
option of :func:`to_datetime` isn't strict, and this can lead to surprising behaviour:
.. ipython:: python :okwarning: pd.to_datetime(["31-12-2021"], dayfirst=False)
Now, a warning will be raised if a date string cannot be parsed accordance to the given dayfirst
value when
the value is a delimited date string (e.g. 31-12-2012
).
Some minimum supported versions of dependencies were updated. If installed, we now require:
Package | Minimum Version | Required | Changed |
---|---|---|---|
numpy | 1.18.5 | X | X |
pytz | 2020.1 | X | X |
python-dateutil | 2.8.1 | X | X |
bottleneck | 1.3.1 | X | |
numexpr | 2.7.1 | X | |
pytest (dev) | 6.0 | ||
mypy (dev) | 0.910 | X |
For optional libraries the general recommendation is to use the latest version. The following table lists the lowest version per library that is currently being tested throughout the development of pandas. Optional libraries below the lowest tested version may still work, but are not considered supported.
Package | Minimum Version | Changed |
---|---|---|
beautifulsoup4 | 4.8.2 | X |
fastparquet | 0.4.0 | |
fsspec | 0.7.4 | |
gcsfs | 0.6.0 | |
lxml | 4.5.0 | X |
matplotlib | 3.3.2 | X |
numba | 0.50.1 | X |
openpyxl | 3.0.2 | X |
pyarrow | 0.17.0 | |
pymysql | 0.10.1 | X |
pytables | 3.6.1 | X |
s3fs | 0.4.0 | |
scipy | 1.4.1 | X |
sqlalchemy | 1.3.11 | X |
tabulate | 0.8.7 | |
xarray | 0.15.1 | X |
xlrd | 2.0.1 | X |
xlsxwriter | 1.2.2 | X |
xlwt | 1.3.0 | |
pandas-gbq | 0.14.0 | X |
See :ref:`install.dependencies` and :ref:`install.optional_dependencies` for more.
Also note that Jinja2
, with minimum version 2.11, has been made a hard dependency to support
DataFrame rendering in LaTeX and HTML formats, where the methods :meth:`DataFrame.to_latex` and
:meth:`DataFrame.to_html` now utilise the :class:`.Styler` template parsing mechanics.
- :meth:`Index.get_indexer_for` no longer accepts keyword arguments (other than 'target'); in the past these would be silently ignored if the index was not unique (:issue:`42310`)
:class:`Int64Index`, :class:`UInt64Index` and :class:`Float64Index` have been deprecated in favor of the new :class:`NumericIndex` and will be removed in Pandas 2.0 (:issue:`43028`).
Currently, in order to maintain backward compatibility, calls to :class:`Index` will continue to return :class:`Int64Index`, :class:`UInt64Index` and :class:`Float64Index` when given numeric data, but in the future, a :class:`NumericIndex` will be returned.
Current behavior:
In [1]: pd.Index([1, 2, 3], dtype="int32")
Out [1]: Int64Index([1, 2, 3], dtype='int64')
In [1]: pd.Index([1, 2, 3], dtype="uint64")
Out [1]: UInt64Index([1, 2, 3], dtype='uint64')
Future behavior:
In [3]: pd.Index([1, 2, 3], dtype="int32")
Out [3]: NumericIndex([1, 2, 3], dtype='int32')
In [4]: pd.Index([1, 2, 3], dtype="uint64")
Out [4]: NumericIndex([1, 2, 3], dtype='uint64')
- Deprecated :meth:`Index.is_type_compatible` (:issue:`42113`)
- Deprecated
method
argument in :meth:`Index.get_loc`, useindex.get_indexer([label], method=...)
instead (:issue:`42269`) - Deprecated treating integer keys in :meth:`Series.__setitem__` as positional when the index is a :class:`Float64Index` not containing the key, a :class:`IntervalIndex` with no entries containing the key, or a :class:`MultiIndex` with leading :class:`Float64Index` level not containing the key (:issue:`33469`)
- Deprecated treating
numpy.datetime64
objects as UTC times when passed to the :class:`Timestamp` constructor along with a timezone. In a future version, these will be treated as wall-times. To retain the old behavior, useTimestamp(dt64).tz_localize("UTC").tz_convert(tz)
(:issue:`24559`) - Deprecated ignoring missing labels when indexing with a sequence of labels on a level of a MultiIndex (:issue:`42351`)
- Creating an empty Series without a dtype will now raise a more visible
FutureWarning
instead of aDeprecationWarning
(:issue:`30017`) - Deprecated the 'kind' argument in :meth:`Index.get_slice_bound`, :meth:`Index.slice_indexer`, :meth:`Index.slice_locs`; in a future version passing 'kind' will raise (:issue:`42857`)
- Deprecated dropping of nuisance columns in :class:`Rolling`, :class:`Expanding`, and :class:`EWM` aggregations (:issue:`42738`)
- Deprecated :meth:`Index.reindex` with a non-unique index (:issue:`42568`)
- Deprecated :meth:`.Styler.render` in favour of :meth:`.Styler.to_html` (:issue:`42140`)
- Deprecated passing in a string column label into
times
in :meth:`DataFrame.ewm` (:issue:`43265`)
- Performance improvement in :meth:`.GroupBy.sample`, especially when
weights
argument provided (:issue:`34483`) - Performance improvement in :meth:`.GroupBy.transform` for user-defined functions (:issue:`41598`)
- Performance improvement in constructing :class:`DataFrame` objects (:issue:`42631`)
- Performance improvement in :meth:`GroupBy.shift` when
fill_value
argument is provided (:issue:`26615`) - Performance improvement in :meth:`DataFrame.corr` for
method=pearson
on data without missing values (:issue:`40956`) - Performance improvement in some :meth:`GroupBy.apply` operations (:issue:`42992`)
- Performance improvement in :func:`read_stata` (:issue:`43059`)
- Performance improvement in :meth:`to_datetime` with
uint
dtypes (:issue:`42606`) - Performance improvement in :meth:`Series.sparse.to_coo` (:issue:`42880`)
- Performance improvement in indexing with a :class:`MultiIndex` indexer on another :class:`MultiIndex` (:issue:43370`)
- Bug in setting dtype-incompatible values into a :class:`Categorical` (or
Series
orDataFrame
backed byCategorical
) raisingValueError
instead ofTypeError
(:issue:`41919`) - Bug in :meth:`Categorical.searchsorted` when passing a dtype-incompatible value raising
KeyError
instead ofTypeError
(:issue:`41919`) - Bug in :meth:`Series.where` with
CategoricalDtype
when passing a dtype-incompatible value raisingValueError
instead ofTypeError
(:issue:`41919`) - Bug in :meth:`Categorical.fillna` when passing a dtype-incompatible value raising
ValueError
instead ofTypeError
(:issue:`41919`) - Bug in :meth:`Categorical.fillna` with a tuple-like category raising
ValueError
instead ofTypeError
when filling with a non-category tuple (:issue:`41919`)
- Bug in :class:`DataFrame` constructor unnecessarily copying non-datetimelike 2D object arrays (:issue:`39272`)
- :func:`to_datetime` would silently swap
MM/DD/YYYY
andDD/MM/YYYY
formats if the givendayfirst
option could not be respected - now, a warning is raised in the case of delimited date strings (e.g.31-12-2012
) (:issue:`12585`)
- Bug in :meth:`Series.dt.tz_convert` resetting index in a :class:`Series` with :class:`CategoricalIndex` (:issue:`43080`)
- Bug in :meth:`DataFrame.rank` raising
ValueError
withobject
columns andmethod="first"
(:issue:`41931`) - Bug in :meth:`DataFrame.rank` treating missing values and extreme values as equal (for example
np.nan
andnp.inf
), causing incorrect results whenna_option="bottom"
orna_option="top
used (:issue:`41931`) - Bug in
numexpr
engine still being used when the optioncompute.use_numexpr
is set toFalse
(:issue:`32556`)
- Bug in :class:`UInt64Index` constructor when passing a list containing both positive integers small enough to cast to int64 and integers too large too hold in int64 (:issue:`42201`)
- Bug in :class:`Series` constructor returning 0 for missing values with dtype
int64
andFalse
for dtypebool
(:issue:`43017`, :issue:`43018`)
- Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` when the object's Index has a length greater than one but only one unique value (:issue:`42365`)
- Bug in :meth:`Series.loc` and :meth:`DataFrame.loc` with a :class:`MultiIndex` when indexing with a tuple in which one of the levels is also a tuple (:issue:`27591`)
- Bug in :meth:`Series.loc` when with a :class:`MultiIndex` whose first level contains only
np.nan
values (:issue:`42055`) - Bug in indexing on a :class:`Series` or :class:`DataFrame` with a :class:`DatetimeIndex` when passing a string, the return type depended on whether the index was monotonic (:issue:`24892`)
- Bug in indexing on a :class:`MultiIndex` failing to drop scalar levels when the indexer is a tuple containing a datetime-like string (:issue:`42476`)
- Bug in :meth:`DataFrame.sort_values` and :meth:`Series.sort_values` when passing an ascending value, failed to raise or incorrectly raising
ValueError
(:issue:`41634`) - Bug in updating values of :class:`pandas.Series` using boolean index, created by using :meth:`pandas.DataFrame.pop` (:issue:`42530`)
- Bug in :meth:`Index.get_indexer_non_unique` when index contains multiple
np.nan
(:issue:`35392`) - Bug in :meth:`DataFrame.query` did not handle the degree sign in a backticked column name, such as `Temp(°C)`, used in an expression to query a dataframe (:issue:`42826`)
- Bug in :meth:`DataFrame.drop` where the error message did not show missing labels with commas when raising
KeyError
(:issue:`42881`) - Bug in :meth:`DataFrame.nlargest` and :meth:`Series.nlargest` where sorted result did not count indexes containing
np.nan
(:issue:`28984`)
- Bug in :meth:`DataFrame.fillna` with limit and no method ignores axis='columns' or
axis = 1
(:issue:`40989`)
- Bug in :meth:`MultiIndex.get_loc` where the first level is a :class:`DatetimeIndex` and a string key is passed (:issue:`42465`)
- Bug in :meth:`MultiIndex.reindex` when passing a
level
that corresponds to anExtensionDtype
level (:issue:`42043`) - Bug in :meth:`MultiIndex.get_loc` raising
TypeError
instead ofKeyError
on nested tuple (:issue:`42440`) - Bug in :meth:`MultiIndex.putmask` where the other value was also a :class:`MultiIndex` (:issue:`43212`)
- Bug in :func:`read_excel` attempting to read chart sheets from .xlsx files (:issue:`41448`)
- Bug in :func:`json_normalize` where
errors=ignore
could fail to ignore missing values ofmeta
whenrecord_path
has a length greater than one (:issue:`41876`) - Bug in :func:`read_csv` with multi-header input and arguments referencing column names as tuples (:issue:`42446`)
- Bug in :func:`read_fwf`, where difference in lengths of
colspecs
andnames
was not raisingValueError
(:issue:`40830`) - Bug in :func:`Series.to_json` and :func:`DataFrame.to_json` where some attributes were skipped when serialising plain Python objects to JSON (:issue:`42768`, :issue:`33043`)
- Column headers are dropped when constructing a :class:`DataFrame` from a sqlalchemy's
Row
object (:issue:`40682`) - Bug in unpickling a :class:`Index` with object dtype incorrectly inferring numeric dtypes (:issue:`43188`)
- Bug in :func:`read_csv` where reading multi-header input with unequal lengths incorrectly raising uncontrolled
IndexError
(:issue:`43102`)
- Fixed bug in :meth:`SeriesGroupBy.apply` where passing an unrecognized string argument failed to raise
TypeError
when the underlyingSeries
is empty (:issue:`42021`) - Bug in :meth:`Series.rolling.apply`, :meth:`DataFrame.rolling.apply`, :meth:`Series.expanding.apply` and :meth:`DataFrame.expanding.apply` with
engine="numba"
where*args
were being cached with the user passed function (:issue:`42287`) - Bug in :meth:`GroupBy.max` and :meth:`GroupBy.min` with nullable integer dtypes losing precision (:issue:`41743`)
- Bug in :meth:`DataFrame.groupby.rolling.var` would calculate the rolling variance only on the first group (:issue:`42442`)
- Bug in :meth:`GroupBy.shift` that would return the grouping columns if
fill_value
was not None (:issue:`41556`) - Bug in :meth:`SeriesGroupBy.nlargest` and :meth:`SeriesGroupBy.nsmallest` would have an inconsistent index when the input Series was sorted and
n
was greater than or equal to all group sizes (:issue:`15272`, :issue:`16345`, :issue:`29129`) - Bug in :meth:`pandas.DataFrame.ewm`, where non-float64 dtypes were silently failing (:issue:`42452`)
- Bug in :meth:`pandas.DataFrame.rolling` operation along rows (
axis=1
) incorrectly omits columns containingfloat16
andfloat32
(:issue:`41779`) - Bug in :meth:`Resampler.aggregate` did not allow the use of Named Aggregation (:issue:`32803`)
- Bug in :meth:`Series.rolling` when the :class:`Series`
dtype
wasInt64
(:issue:`43016`) - Bug in :meth:`DataFrame.rolling.corr` when the :class:`DataFrame` columns was a :class:`MultiIndex` (:issue:`21157`)
- Bug in :meth:`DataFrame.groupby.rolling` when specifying
on
and calling__getitem__
would subsequently return incorrect results (:issue:`43355`)
- Improved error message when creating a :class:`DataFrame` column from a multi-dimensional :class:`numpy.ndarray` (:issue:`42463`)
- :func:`concat` creating :class:`MultiIndex` with duplicate level entries when concatenating a :class:`DataFrame` with duplicates in :class:`Index` and multiple keys (:issue:`42651`)
- Bug in :meth:`pandas.cut` on :class:`Series` with duplicate indices (:issue:`42185`) and non-exact :meth:`pandas.CategoricalIndex` (:issue:`42425`)
- Bug in :meth:`DataFrame.append` failing to retain dtypes when appended columns do not match (:issue:`43392`)
- Bug in :func:`concat` of
bool
andboolean
dtypes resulting inobject
dtype instead ofboolean
dtype (:issue:`42800`)
- Minor bug in :class:`.Styler` where the
uuid
at initialization maintained a floating underscore (:issue:`43037`) - Bug in :meth:`.Styler.to_html` where the
Styler
object was updated if theto_html
method was called with some args (:issue:`43034`) - Bug in :meth:`.Styler.copy` where
uuid
was not previously copied (:issue:`40675`) - Bug in :meth:`Styler.apply` where functions which returned Series objects were not correctly handled in terms of aligning their index labels (:issue:`13657`, :issue:`42014`)
- Bug when rendering an empty DataFrame with a named index (:issue:`43305`).
- Bug when rendering a single level MultiIndex (:issue:`43383`).
- Bug in :meth:`CustomBusinessMonthBegin.__add__` (:meth:`CustomBusinessMonthEnd.__add__`) not applying the extra
offset
parameter when beginning (end) of the target month is already a business day (:issue:`41356`)