What’s new in 3.1.0 (Month XX, 2026)#
These are the changes in pandas 3.1.0. See Release notes for a full changelog including other versions of pandas.
Enhancements#
enhancement1#
enhancement2#
Other enhancements#
Periodnow supports f-string formatting via__format__, e.g.f"{period:%Y-%m}"(GH 48536)SeriesandDataFramewithtimedelta64dtype now aligns fractional seconds in string representation for easier reading (GH 57188)DataFrameGroupBy.agg()now allows for the providedfuncto return a NumPy array (GH 63957)DataFrameGroupBy.transform()now accepts list-like and dict arguments similar toGroupBy.agg(), and supportsNamedFunc(GH 58318)Series.to_json()now supports serializing custom ExtensionArrays (by correctly using the_values_for_jsonmethod of an ExtensionArray) (GH 65047)Timestamp.round(),Timestamp.floor(), andTimestamp.ceil()now officially acceptTimedeltaarguments (GH 63687)Added
NamedFunc, an alias toNamedAggfor a more semantically accurate name when used with non-aggregation functions; either can accept arbitrary functions (GH 65164)ExtensionArray.map()now callsExtensionArray._cast_pointwise_result()to retain the dtype backend, e.g. Arrow-backed arrays now preserve their Arrow dtype throughmap(GH 57189, GH 62164)read_csv()now supportsdtype="complex64"anddtype="complex128"with the C engine, enabling round-tripping of complex-number columns written byDataFrame.to_csv()(GH 9379)to_datetime()andstrptimeparsing now support the%Ndirective for matching exactly 9 digits representing nanoseconds, providing symmetry withstrftimeformatting (GH 65863)DataFrame.select_dtypes()can now selectdatetime64andtimedelta64columns by a specific resolution (e.g."datetime64[us]",np.dtype("timedelta64[ms]")), which previously raised; a unit-specific spec matches only columns with exactly that resolution, while a unitless"datetime64"/"timedelta64"still matches every resolution (GH 40234)Series.round()now works on third-party numericExtensionArraytypes via a defaultExtensionArray.round()(GH 49387)Timestamp.strftime()and the array-levelDatetimeIndex.strftime()/Series.dt.strftime()now support a%Ndirective that formats nanoseconds as a 9-digit zero-padded number; the standard%fdirective is unchanged and continues to format microseconds only (GH 29461)Added
ExtensionArray.count()(GH 64450)Added
ExtensionArray.sort()for in-place sorting ofExtensionArray(GH 64977)Added
Index.replace()method to support value replacement functionality similar toSeries.replace()(GH 19495)Added reduction methods as public API on pandas-implemented extension arrays where applicable (GH 63512)
Display formatting for float sequences in DataFrame cells now respects the
display.precisionoption (GH 60503).Improved the precision of float parsing in
read_csv()(GH 64395)Improved the string
reprofpd.core.arrays.SparseArray(GH 64547)Improved type inference of comparison and arithmetic operators on
SeriesandDataFramefor static type checkers (e.g.ser == "a"is now inferred asSeriesinstead ofAny) (GH 40762)MSVC is no longer required to build on Windows, and build errors when using the MinGW compiler have been fixed (GH 63160)
Setting values with
DataFrame.at()orSeries.at()using a non-scalar indexer (e.g. a boolean mask, list, or array) now raises a clearerInvalidIndexErrordirecting users to.loc(GH 51866)
Notable bug fixes#
These are bug fixes that might have notable behavior changes.
Timedelta.total_seconds now includes the nanosecond component#
Previously Timedelta.total_seconds() mirrored the stdlib
datetime.timedelta.total_seconds() formula and silently dropped the
sub-microsecond nanosecond residual — e.g. Timedelta(nanoseconds=999).total_seconds()
returned 0.0 instead of 9.99e-7. The result now includes the
nanosecond component. The vectorized TimedeltaIndex.total_seconds() and
Series.dt.total_seconds() already included the nanosecond component;
they now match the scalar result exactly, including at large magnitudes
where floating-point rounding previously differed (GH 46819).
notable_bug_fix2#
Backwards incompatible API changes#
Increased minimum versions for dependencies#
Some minimum supported versions of dependencies were updated. If installed, we now require:
Package |
Minimum Version |
Required |
Changed |
|---|---|---|---|
X |
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 |
|---|---|---|
X |
See Dependencies and Optional dependencies for more.
Other API changes#
Index.valuesandIndex.arraynow return read-only arrays for all dtypes, so anIndexcan no longer be silently corrupted by mutating the returned array in place (previously this left the Index displaying the new value while lookups still used the old one) (GH 38547)infer_freq()on quarter-start data now reports the equivalent anchor from the first calendar quarter, e.g.QS-JANinstead ofQS-OCT(GH 36939)testing.assert_frame_equal()withcheck_freq=Truenow also checks thefreqofDatetimeIndexandTimedeltaIndexcolumns; previously only thefreqof the index was checked (GH 51920)testing.assert_series_equal()withcheck_index=Falseno longer checks thefreqattribute of aDatetimeIndexorTimedeltaIndex, asfreqis an attribute of the index (GH 51920)DataFrameGroupBy.sum()andDataFrameGroupBy.mean()on float dtypes with sorted grouping keys may differ from prior versions in the last few floating-point digits, due to a faster summation algorithm that does not use Kahan compensation (GH 65103)DataFrame.select_dtypes()now selects only columns with exactly the given dtype when a dtype instance is passed toincludeorexclude. Previously an instance selected all columns with a matchingdtype.type, e.g.pd.DatetimeTZDtype(tz="UTC")also selected other timezones,np.dtype("int64")also selectedInt64and Arrowint64columns, andpd.CategoricalDtype(["a", "b"])selected every categorical column (GH 40234)DataFrame.to_hdf()no longer writes apandas_versionattribute into the HDF5 file; the value was hardcoded to"0.15.2"and never reflected the pandas version. As a consequence,format="table"files written with pandas 3.1 or later cannot be read by pandas 3.0 or earlier (GH 62792)APIs that accept an
engine="numba"parameter withengine_kwargswill no longer pass through anopythonargument tonumba.jit. This argument has had no effect since numba 0.59.0 (GH 64483).Removed the
freqandfreqstrattributes fromDatetimeArrayandTimedeltaArray. Frequency is now stored only onDatetimeIndexandTimedeltaIndex; accessSeries.dt.freqor wrap the array in an Index to retrieve a frequency. Thecheck_freqkeyword ontesting.assert_extension_array_equal()for these array types has also been removed (GH 24566).
Deprecations#
Added
check_freqkeyword totesting.assert_index_equal()with a deprecated default: currently afreqmismatch on aDatetimeIndexorTimedeltaIndexonly warns; in a future versioncheck_freq=Truewill be the default and mismatches will raise. The same deprecation applies to thefreqofDatetimeIndex/TimedeltaIndexcolumns intesting.assert_frame_equal(), which were previously never checked. Passcheck_freqexplicitly to silence the warning (GH 51920)Deprecated
Timestamp.dayofweek,Timestamp.dayofyear,Timestamp.daysinmonthin favor ofTimestamp.day_of_week,Timestamp.day_of_year,Timestamp.days_in_month, respectively. The same deprecation applies to the corresponding attributes onPeriod,DatetimeIndex,PeriodIndex, andSeries.dt(GH 46768)Deprecated
PeriodIndexandPeriodArrayinferring the frequency from aSeriesof datetime64 data whenfreqis not provided. Passfreqexplicitly instead (GH 64241)Deprecated
infer_freq(),DatetimeIndex.inferred_freq, andTimedeltaIndex.inferred_freqreturning a string; in a future version these will return aBaseOffsetinstead. Usepd.set_option('future.infer_freq_returns_offset', True)to opt in to the future behavior (GH 55504)Deprecated
set_eng_float_format(). Usepd.set_option("display.precision", N)to control decimal precision, or pass a custom callable topd.set_option("display.float_format", func)(GH 64460)Deprecated
DataFrameGroupBy.agg()andResampler.agg()unpacking a scalar when the providedfuncreturns a Series or array of length 1; in the future this will result in the Series or array being in the result. Users should unpack the scalar infuncitself (GH 64014)Deprecated
ExcelFile.parse(), useread_excel()instead (GH 58247)Deprecated
Series.fillna(),DataFrame.fillna(), andIndex.fillna()with an incompatible value that requires dtype casting. In a future version, this will raise instead. Explicitly cast to a common dtype before filling (GH 45153)Deprecated
engine="fastparquet"andengine="auto"inread_parquet()andDataFrame.to_parquet(). Thefastparquetlibrary has been retired; useengine="pyarrow"or do not passengineto use the default. (GH 64597)Deprecated arithmetic operations between pandas objects (
DataFrame,Series,Index, and pandas-implementedExtensionArraysubclasses) and list-likes other thanlist,np.ndarray,ExtensionArray,Index,Series,DataFrame. For e.g.tupleorrange, explicitly cast these to a supported object instead. In a future version, these will be treated as scalar-like for pointwise operation (GH 62423)Deprecated automatic dtype promotion when reindexing with a
fill_valuethat cannot be held by the original dtype. Explicitly cast to a common dtype instead (GH 53910)Deprecated expanding a
DataFrameorSerieswith aMultiIndexusing a key that is not a full-length tuple (e.g.,df.loc["x"] = valuesordf["x"] = values). Use a full-length tuple key instead (e.g.,df.loc[("x", ""), :] = valuesfor rows ordf[("x", "")] = valuesfor columns), or calldf.index = df.index.to_flat_index()before expanding (GH 17024)Deprecated grouping by an index level name when the name matches multiple levels of a
MultiIndex. Use the level number instead (GH 49434)Deprecated implicit conversion of
datetime.dateobjects toTimestampwhen indexing or joining aDatetimeIndex. Useto_datetime()to explicitly convert toDatetimeIndexinstead (GH 62158)Deprecated passing a
dicttoDataFrame.from_records(), use theDataFrameconstructor orDataFrame.from_dict()instead (GH 22025)Deprecated passing a
formatfor integer or float columns toread_sql(),read_sql_query(), andread_sql_table()viaparse_dates. Cast the column to string and callto_datetime()after reading instead (GH 55663)Deprecated passing a non-dict (e.g. a list of dicts) to
DataFrame.from_dict(). Use theDataFrameconstructor instead (GH 58862)Deprecated passing integer or float values to
to_datetime()with aformatargument. Cast numeric values to strings explicitly first to retain the current behavior (GH 55663)Deprecated passing unnecessary
*argsand**kwargstoGroupBy.cumsum(),GroupBy.cumprod(),GroupBy.cummin(),GroupBy.cummax(),SeriesGroupBy.skew(),DataFrameGroupBy.skew(),SeriesGroupBy.take(), andDataFrameGroupBy.take(). Theskipnaparameter for the cum* methods is now an explicit keyword argument (GH 50407)Deprecated relying on the default
enginefor.xlsxand.xlsmfiles inread_excel()andExcelFilewhenpython-calamineis installed; the default will change fromopenpyxltocalaminein a future version. Passengineexplicitly, or set theio.excel.xlsx.readeroption, to silence the warning (GH 56542)Deprecated setting values with
DataFrame.at()andSeries.at()when the key does not exist in the index, which previously expanded the object. Use.locinstead (GH 48323)Deprecated the
%ndirective inPeriod.strftime()for nanoseconds; use%Ninstead.%nis a newline directive in Cstrftime(and Python’stime.strftime/datetime.strftime) (GH 65432)Deprecated the
.nameproperty of offset objects (e.g.,Day,Hour). Use.rule_codeinstead (GH 64207)Deprecated the
convert_datesandkeep_default_dateskeywords inread_json(). Passdtype=Falseto disable type conversion, or parse date columns withto_datetime()after reading (GH 59161)Deprecated the
dropnakeyword inDataFrame.to_hdf(),HDFStore.put(),HDFStore.append(), andHDFStore.append_to_multiple(), and theio.hdf.dropna_tableoption. UseDataFrame.dropna()before writing instead (GH 32038)Deprecated the
float_precisionargument inread_csv(),read_table(), andread_fwf(). All float precision modes now use the same converter (GH 64395)Deprecated the
includeandexcludearguments ofSeries.describe(). They had no effect on a Series; filter dtypes upstream of the call instead (GH 54193)Deprecated the
weekdayproperty onDatetimeIndex,DatetimeArray,PeriodIndex,PeriodArray, andPeriod. Useday_of_weekinstead.Timestamp.weekday()remains a method consistent withdatetime.datetime.weekday()(GH 12816)Deprecated the
xlrdandpyxlsbengines inread_excel(). Useengine="calamine"instead (GH 56542)Deprecated the default value of
exactinassert_index_equal(); in a future version this will default toTrueinstead of “equiv” (GH 57436)Deprecated the default value of
track_timesinHDFStore.put(). In a future version, the default will change fromTruetoFalseso that HDF5 files are deterministic by default (GH 51456)Deprecated the inference of
datetime64dtype from data containingdatetime.dateobjects when used in comparisons orIndex.equals()withDatetimeIndex. Usepandas.to_datetime()to explicitly convert todatetime64instead (GH 65056)Deprecated the keyword
by_blocksintesting.assert_frame_equal()(GH 65911)Deprecated the lossy behavior of
Series.values,Index.values,PeriodIndex.values, andDatetimeIndex.valuesforDatetimeTZDtype(drops timezone),PeriodDtype(returns object-dtype ndarray), andIntervalDtype(returns object-dtype ndarray) dtypes. In a future version,.valueswill return the underlying ExtensionArray. Useto_numpy()orarrayinstead (GH 54717, GH 55128).Deprecated treating array-like objects other than
numpy.ndarray,ExtensionArray,Index, andSeriesas array-like when indexing, setting values, and in related operations. Objects that are merely list-like with adtypeattribute (e.g. arrays from other libraries) will no longer receive array-like handling in a future version; convert them withnumpy.asarray()orpandas.array()first (GH 52834)The default
date_format="epoch"deprecation warning inDataFrame.to_json()andSeries.to_json()is now also emitted when the datetime-like values are in the index or column labels rather than in the column values (GH 65868)Deprecated passing a non-boolean value for
numeric_onlytoDataFrame.mean(),DataFrame.min(),DataFrame.max(),DataFrame.median(),DataFrame.skew(),DataFrame.kurt(),DataFrame.std(),DataFrame.var(),DataFrame.sem(),DataFrame.sum(),DataFrame.prod()(and theirSeriesequivalents); this will raise in a future version of pandas (GH 53098)Deprecated
inplacekeyword forDataFrame.rename()andDataFrame.drop(). This keyword will be removed in a future version (GH 63207); see also PDEP-8
Performance improvements#
Performance improvement in
DataFrameGroupByaggregations (sum,mean,min,max,prod) when the grouping keys are already sorted (GH 65103)Performance improvement in casting integer and boolean dtypes to
string[pyarrow]by using PyArrow’s native cast instead of element-wise conversion (GH 56505)Performance improvement in
DataFrame.__getitem__()when selecting a single column by label on aDataFramewith duplicate column names. (GH 64126).Performance improvement in
DataFrame.dtypeswhen accessed repeatedly (GH 65382)Performance improvement in
Series.is_monotonic_increasingandSeries.is_monotonic_decreasingforArrowDtypeand masked dtypes by dispatching to theExtensionArray(GH 56619)Performance improvement in
DataFramerepr by avoiding redundant formatting when columns exceed terminal width (GH 64863)Performance improvement in
DatetimeIndexandSeriesconstruction with a timezone-awaredatetime64dtype from a sequence of strings (GH 66123)Performance improvement in
GroupByreductions and transformations forSparseDtypecolumns (GH 36123)Performance improvement in
bdate_range()anddate_range()withfreq="B"orfreq="C"(business day frequencies) (GH 16463)Performance improvement in
concat()andDataFrame.astype()to extension dtypes (GH 65672)Performance improvement in
concat()by avoiding redundant comparisons of equal indexes (GH 65393)Performance improvement in
factorize()withsort=True(GH 66127)Performance improvement in
infer_freq()(GH 64463)Performance improvement in
merge()andDataFrame.join()for many-to-many joins withsort=False(GH 56564)Performance improvement in
merge()andDataFrame.join()withhow="outer"orsort=True(GH 66127)Performance improvement in
merge()for many-to-one joins with unique right keys (GH 38418)Performance improvement in
merge()withhow="cross"(GH 38082)Performance improvement in
merge()withhow="left"(GH 64370)Performance improvement in
merge()withhow="left"andsort=Falsewhen joining on a right index with unique keys (GH 65160)Performance improvement in
merge()withsort=Falsefor single-keyhow="left"/how="right"joins when the opposite join key is sorted, unique, and range-like (GH 64146)Performance improvement in
read_csv()withengine="c"(GH 64515)Performance improvement in
read_csv()withengine="c"andparse_datesfor columns containing ISO8601 datetime strings; concurrent reads from multiple threads also scale better (GH 65353, GH 66278)Performance improvement in
read_csv()withengine="c"during dtype inference: columns that do not parse as numeric or boolean (e.g. string columns) are now rejected before allocating a result buffer for the attempt (GH 66273)Performance improvement in
read_csv()withengine="c"for float columns (GH 65767)Performance improvement in
read_csv()withengine="c"for float columns with default settings (GH 66239)Performance improvement in
read_csv()withengine="c"for integer and string columns (GH 65350)Performance improvement in
read_csv()withengine="c"for large uncompressed local files, which are now read in parallel across multiple CPU cores; this is enabled by default except on Windows and can be controlled with themode.max_threadsoption (GH 64347)Performance improvement in
read_csv()withengine="c"for string columns underfuture.infer_stringordtype_backend="pyarrow", particularly when strings do not repeat (GH 65283)Performance improvement in
read_csv()withengine="c"when an extension dtype is requested (e.g.dtype="Int64",dtype="boolean", ordtype="int64[pyarrow]") (GH 66279)Performance improvement in
read_csv()withengine="c"when parsing integer columns (GH 65347)Performance improvement in
read_csv()withengine="c"when reading from binary file-like objects (e.g. PyArrow S3 file handles) by avoiding unnecessaryTextIOWrapperwrapping (GH 46823)Performance improvement in
read_csv()withengine="c"when reading in parallel: closing a parser no longer blocks the other parser threads while its buffers are freed (GH 66272)Performance improvement in
read_csv()withengine="c", especially for large files and parallel reads (GH 66271)Performance improvement in
read_hdf()for the fixed (default) format, especially on large frames (GH 47726)Performance improvement in
read_html()and the Python CSV parser whenthousandsis set, fixing catastrophic regex backtracking on cells with many comma-separated digit groups followed by non-numeric text (GH 52619)Performance improvement in
read_sas()by reading page header fields directly in Cython instead of falling back to Python (GH 47339)Performance improvement in
read_sas()for SAS7BDAT files by pre-computing date/datetime column classification once during metadata parsing instead of per chunk (GH 47339)Performance improvement in
read_sas()for SAS7BDAT files with full-precision (8-byte) numeric columns, with up to ~2x speedup on bulk reads (GH 47339)Performance improvement in
read_sas()for compressed SAS7BDAT files by reusing the decompression buffer instead of allocating per row (GH 47339)Performance improvement in
read_sas()when decoding strings (GH 47339)Performance improvement in
read_sql()with ADBC connections by requesting only table metadata when checking whether an input string names a table (GH 65652)Performance improvement in
to_datetime()and theTimestampconstructor when parsing strings with timezone offsets (GH 66123)Performance improvement in
to_datetime()when passed aDataFrameof date/time field columns (GH 65195)Performance improvement in
to_datetime()with the defaultcache=Truefor inputs that are already datetime-typed or use aunit(GH 65380)Performance improvement in
tseries.frequencies.to_offset()parsing of frequency strings, especially for tick-resolution offsets (e.g."h","5min","3s") and compound expressions (e.g."1D1h") (GH 65395)Performance improvement in
util.hash_pandas_object()for PyArrow-backed string and binary types by using PyArrow’sdictionary_encodeinstead of converting to NumPy for factorization (GH 48964)Performance improvement in
DataFrameGroupBy.agg()andSeriesGroupBy.agg()with user-defined functions (GH 46505)Performance improvement in
DataFrame.apply()withaxis=1when theDataFramehasExtensionDtypecolumns (e.g.ArrowDtype) (GH 61747)Performance improvement in
DataFrame.corr()andDataFrame.cov()when data contains no NaN values (GH 64857)Performance improvement in
DataFrame.corr()formethod="kendall"(GH 28329)Performance improvement in
DataFrame.diff()(GH 64864)Performance improvement in
DataFrame.equals(),DataFrame.select_dtypes(), and other operations performing shallow column slicing on Arrow-backed columns (GH 58966)Performance improvement in
DataFrame.fillna()andSeries.fillna()with scalar fill value for float, object, nullable, and datetime-like dtypes (GH 42147)Performance improvement in
DataFrame.from_records()when passing a 2Dnumpy.ndarray(GH 22025)Performance improvement in
DataFrame.insert()when the number of blocks is small (GH 57641)Performance improvement in
DataFrame.loc()with non-unique masked index (GH 56759)Performance improvement in
DataFrame.plot()for line plots of wide DataFrames with aDatetimeIndexorPeriodIndex(GH 61398)Performance improvement in
DataFrame.query()andDataFrame.eval()when theDataFramecontainsPeriodDtypeorIntervalDtypecolumns (GH 35247)Performance improvement in
DataFrame.rank()andSeries.rank()for non-nullable numeric dtypes (GH 65054)Performance improvement in
DataFrame.sort_index()andSeries.sort_index()with thelevelparameter when the index is already sorted and not aMultiIndex(GH 64883)Performance improvement in
DataFrame.sort_values()with multiple numeric columns by avoiding unnecessaryCategoricalconversion (GH 15389)Performance improvement in
DataFrame.sum(),DataFrame.prod(),DataFrame.min(),DataFrame.max(),DataFrame.mean(),DataFrame.any(), andDataFrame.all()withaxis=1for multi-block DataFrames by avoiding a transpose (GH 51474)Performance improvement in
DataFrame.take(),Series.take(),DataFrame.reindex(),Series.reindex(), and boolean-array indexing for NumPy-backed dtypes (GH 65295)Performance improvement in
DataFrame.to_excel()with theopenpyxlengine when usingengine_kwargs={"write_only": True}, reducing memory consumption (GH 41681)Performance improvement in
DataFrame.to_hdf()andHDFStore.append()for table format when appending to an existing wide table with manydata_columns(GH 25839)Performance improvement in
DataFrame.to_stata()when writing object-dtype datetime columns with date formats that require year/month extraction (GH 64555)Performance improvement in
DataFrame.unstack()andSeries.unstack()when theMultiIndexis already sorted and the unstacked level is the last level (GH 65107)Performance improvement in
DataFrame.xs()andSeries.xs()with a partial key on aMultiIndex(GH 38650)Performance improvement in
DataFrame()reductions (e.g.DataFrame.any(),DataFrame.sum(),DataFrame.idxmax()) withaxis=1on extension array dtypes such asBooleanDtype, nullable integer/float, andArrowDtype(GH 56903)Performance improvement in
DatetimeIndex.month_name()andDatetimeIndex.day_name()when using the default string dtype by using PyArrow compute instead of going through an intermediate object array (GH 65104)Performance improvement in
DatetimeIndex.strftime()andSeries.dt.strftime()for formats composed of common directives (%Y,%m,%d,%H,%M,%S,%f) (GH 44764)Performance improvement in
GroupBy.any()andGroupBy.all()for boolean-dtype columns (GH 37850)Performance improvement in
GroupBy.first()andGroupBy.last()for Extension Array dtypes, which no longer fall back to a slowapply-based implementation (GH 57591)Performance improvement in
GroupBy.quantile()(GH 64330)Performance improvement in
GroupBy.size()(GH 51750)Performance improvement in
HDFStore.select_as_multiple()when nowhereclause is given, by avoiding a coordinate-based read (GH 26771)Performance improvement in
Index.factorize()for a monotonicDatetimeIndexorTimedeltaIndexwithout afreq(GH 66046)Performance improvement in
Index.get_indexer_non_unique(), and consequently in indexing and reindexing with duplicate labels, for numeric and datetime-like dtypes,MultiIndex, and nullable dtypes without missing values (GH 66125)Performance improvement in
Index.get_indexer()for large monotonic indexes, which now uses binary search instead of building a hash table when the number of targets is small (GH 14273)Performance improvement in
Index.join()andIndex.union()forRangeIndexby avoiding unnecessary memory allocation in the libjoin fastpath (GH 54646)Performance improvement in
IntervalIndex.get_indexer()for monotonic non-overlapping indexes, which now uses binary search instead of the interval tree (GH 47614)Performance improvement in
NDFrame.__finalize__(),Series.to_numpy(),DataFrame.dtypes, andDataFrame.__getitem__()(GH 57431)Performance improvement in
PeriodIndex.from_fields()(GH 65921)Performance improvement in
Series.corr()withmethod="pearson"by avoiding an unnecessary correlation matrix calculation for 1D inputs (GH 65502)Performance improvement in
Series.skew(),Series.kurt(), and theirDataFramecounterparts when axis isNoneor0(GH 64884)Performance improvement in
Series.str.isascii()forStringDtypewith storage"pyarrow", which fell back to an object-dtype implementation instead of using PyArrow’sstring_is_asciikernel (GH 66335)Performance improvement in
Series.str.zfill()forStringDtypewith storage"pyarrow", which fell back to an object-dtype implementation instead of using PyArrow’sutf8_zfillkernel (GH 66339)Performance improvement in
Series.to_json()andDataFrame.to_json()withdate_format="iso"for a timezone-aware datetimeSeriesand for a timezone-awareDatetimeIndex(GH 66007)Performance improvement in
Timedelta.total_seconds()(GH 65388)Performance improvement in
arrays.SparseArray.isna()by avoiding a dense-then-resparsify round-trip (GH 41023)Performance improvement in datetime/timedelta unit conversion (e.g.
datetime64[s]todatetime64[ns]) (GH 35025)Performance improvement in indexing a
DataFramewith aCategoricalIndexofIntervalcategories (GH 61928)Performance improvement in indexing a
MultiIndexwith a list-like indexer (GH 55786)Performance improvement in partial-string indexing on a monotonic decreasing
DatetimeIndexorPeriodIndex(GH 64811)Performance improvement in plotting
DatetimeIndexwith multiplied frequencies (e.g."1000ms","100s") (GH 50355)Performance improvement in plotting
SeriesandDataFramewith aPeriodIndexor with aDatetimeIndexwhose frequency upsamples to one (GH 10578)Performance improvement in reading zip-compressed files (e.g.
read_pickle(),read_csv()) on Python < 3.12 (GH 59279)Performance improvement in reductions along
axis=1and other operations on DataFrames produced byDataFrame.copy()(GH 60469)Performance improvement in reductions with
axis=1(e.g.DataFrame.sum(),DataFrame.mean(),DataFrame.std()), especially on single-dtype DataFrames with many rows (GH 51474)Performance improvement in repr of
SeriesandDataFramecontaining third-party array-like objects (e.g. xarrayDataArray) in object dtype columns (GH 61809)Performance improvement in
DataFrame.loc()andDataFrame.iloc()setitem with a 2D list-of-lists value by avoiding a wasteful round-trip through an intermediate object array (GH 64229).Performance improvement in
Series.reindex()andDataFrame.reindex()for non-nanoseconddatetime64andtimedelta64dtypes (GH 24566)Performance improvement in
Series.iloc()andDataFrame.iloc()when setting datetimelike values into object-dtype data with list-like indexers (GH 64250).Performance improvement in
Series.isin()andDataFrame.isin()whenvaluesis asetorfrozensetand the caller has integer or boolean dtype (GH 25507).Performance improvement in
Series.isin()andDataFrame.isin()when checking a numericSeriesorIndexagainst a list-like of integers of a different numeric dtype (GH 46485).Performance improvement in the
Series.dtduration component accessors (days,seconds,microseconds,nanoseconds,components, etc.) forArrowDtypedurations by using PyArrow compute instead of converting toTimedeltaArray(GH 63470)Performance improvement in tab completion and
DataFrame.__dir__()forDataFrameandSerieswith a large string-valued index or large number of columns (GH 18587).
Bug fixes#
Fixed bug in
Indexrepr where attributes were not wrapped to respectdisplay.width(GH 11552)Fixed bug in
Serieswhere empty frozensets were formatted incorrectly (GH 66192)Fixed bug in
testing.assert_series_equal()showing a misleading class mismatch message when Series values were backed by differentnumpy.ndarraysubclasses (GH 65770)Fixed bug in
to_timedelta()andTimedeltanot accepting Day offsets (GH 64240)
Categorical#
Bug in
Categorical.__repr__()where the values and categories lines could exceeddisplay.width(GH 12066)Bug in
Categorical.map()andSeries.map()raisingNotImplementedErrorwhen the mapper returned tuples for the categories, instead of returning anIndexof tuples (GH 51488)Bug in
Categorical.map()where mapping with adefaultdictandna_action=Nonewould bypass the default factory by usingdict.get, causingNAvalues to be replaced withNaNinstead of the mapper’s default value (GH 62710)Bug in
CategoricalIndex.union()andCategoricalIndex.intersection()giving incorrect results when the two indexes have the same unordered categories in different orders (GH 55335)Bug in
Index.fillna()raisingTypeErrorwhen filling with a tuple value (e.g. on object-dtype orCategoricalIndexwith tuple categories) (GH 37681)
Datetimelike#
Bug in
ArrowExtensionArraywhere adding aDateOffsetto adate32[pyarrow]ordate64[pyarrow]Series raised anArrowTypeError(GH 57168)Bug in
DatetimeIndexconstructor raisingValueErrorwhen passing equivalent but not equal frequencies (e.g.QS-FEBvsQS-MAY) (GH 61086)Bug in
DatetimeIndexraisingAttributeErrorwhen comparing against Arrow date types (date32, date64) (GH 62051)Bug in
Timestampconstructor where passingnp.str_objects would fail in Cython string parsing (GH 48974)Bug in
Timestampconstructor where strings with a negative year of fewer than 4 digits (e.g."-111-01-01") silently dropped the leading"-"and were parsed as a positive year; BC dates with 1-4 digit years now parse correctly, matchingnumpy.datetime64(GH 55954)Bug in
Timestampconstructor,Timedeltaconstructor,to_datetime(), andto_timedelta()with non-roundfloatinput andunitfailing to raise when the value is just outside the representable bounds (GH 57366)Bug in
api.types.infer_dtype()returning"date"or"mixed"instead of"datetime"/"timedelta"for lists ofTimestamp/Timedeltavalues mixed withpd.NA(GH 53023)Bug in
date_range()whereinclusive="left"andinclusive="right"returned a single-element result instead of empty whenstartequalsend(GH 55293)Bug in
date_range()whereinclusiveparameter failed to filter endpoints when onlystartandperiodsorendandperiodswere specified (GH 46331)Bug in
date_range()whereperiods=1with offsets that disallown=0(e.g.offsets.LastWeekOfMonth,offsets.FY5253) raisedValueError(GH 41563)Bug in
date_range()where offsets that preservestart’s time-of-day (e.g.MS,ME,QS,YS,B,C) could exclude the last offset boundary whenend’s time-of-day was earlier thanstart’s (GH 35342)Bug in
date_range()where passingendoff the offset together withperiodsand an anchored offset (e.g.W-SUN,ME,MS,QS) silently returned fewer thanperiodsdates (GH 64834)Bug in
to_datetime()andTimestampwhere a datetime near the implementation bounds with a fixed UTC offset silently wrapped when shifted to UTC instead of raisingOutOfBoundsDatetime(GH 65353)Bug in
to_datetime()andto_timedelta()on ARM platforms where roundfloatvalues outside the int64 domain (e.g.float(2**63)) could silently produce incorrect results instead of raising (GH 64619)Bug in
to_datetime()andto_timedelta()whereuint64values greater thanint64max silently overflowed instead of raisingOutOfBoundsDatetimeorOutOfBoundsTimedelta(GH 60677)Bug in
to_datetime()when passed aDataFrameof date/time field columns raising for years outside the range 1000-9999 (GH 65195)Bug in
to_datetime()when passed aDataFrameof date/time field columns witherrors="coerce"returningdatetime64[s]dtype instead ofdatetime64[us]when all rows were invalid (GH 65195)Bug in
to_datetime()when using a low time resolutionunit, higher resolution inoriginis now preserved instead of silently dropped (e.g.unit="D"with microsecond precision origin) (GH 63419)Bug in
DataFrame.replace()andSeries.replace()raisingAssertionErrorinstead ofOutOfBoundsDatetimewhen replacing with adatetimevalue outside thedatetime64[ns]range (GH 61671)Bug in
DataFrame.to_string()andSeries.to_string()wherena_repwas ignored for datetime and timedelta columns, always displayingNaT(GH 55426)Bug in
DatetimeArray.isin()andTimedeltaArray.isin()where mismatched resolutions could silently truncate finer-resolution values, leading to false matches (GH 64545)Bug in
DatetimeIndex.intersection()returning incorrect results when the two indexes had matchingfreqbut did not lie on the same grid, e.g. ranges with the same business-day frequency but different time-of-day components (GH 44025)Bug in
DatetimeIndex.union()andTimedeltaIndex.union()withsort=Falsesilently dropping values from the other index that fell after the end ofself(GH 66322)Bug in
Series.dt.isocalendar()with a pyarrow-backed datetime or date dtype not preserving the original index, resetting it to a defaultRangeIndex(GH 65894)Bug in adding a
DateOffsetwith amillisecondscomponent to aTimestampreturning a microsecond-resolution result, inconsistent with the millisecond-resolution result of the equivalentDatetimeIndexandSeriesoperations (GH 64806)Bug in adding non-nano
DatetimeIndexwith non-vectorized offsets (e.g.CustomBusinessDay,CustomBusinessMonthEnd) having a sub-unitoffsetparameter incorrectly truncating the result or raisingAttributeError(GH 56586)Bug in subtracting
BusinessHour(orCustomBusinessHour) from aTimestampgiving incorrect results when the subtraction would land exactly on the business-hour opening time (GH 33682)
Timedelta#
Bug in
TimedeltaIndex.resolutionraising when the index has no frequency (GH 65186)Bug in
DateOffsetwhereDateOffset(1)andDateOffset(days=1)returned different results near daylight saving time transitions (GH 61862)Bug in
Timedeltaconstructor andto_timedelta()raising a bareOverflowErrorinstead ofOutOfBoundsTimedeltafor infinite or overflowing float input, which also preventederrors="coerce"from returningNaT(GH 63275)Bug in
Timedeltaconstructor andto_timedelta()where passingnp.str_objects would fail in Cython string parsing (GH 48974)Bug in
Timedeltaconstructor where keyword arguments (e.g.days=365000) that exceeded nanosecond int64 bounds raisedOutOfBoundsTimedeltainstead of falling back to a coarser resolution (GH 46587)Bug in
Series.sum()andDataFrame.sum()on an overflowingtimedelta64object whereSeries.sum()raised a plainValueErrorandDataFrame.sum()silently returned a saturated result instead of raisingOutOfBoundsTimedelta(GH 43178)Bug in
Series.dt.secondsandSeries.dt.microsecondswithArrowDtypedurations returning theSeries.dt.componentsfield values (e.g. 0-59 for seconds, or 0 formicrosecondson a"ms"unit) instead of the totals within each day and second respectively, inconsistent with NumPy-backed timedeltas (GH 63470)Bug in multiplying a
Seriesoftimedelta64by an integer or float, or dividing it by a float, where an overflowing result silently wrapped or saturated instead of raisingOutOfBoundsTimedelta; multiplying byinfnow raisesOutOfBoundsTimedeltainstead of returningNaT(GH 43178)Bug in the
SeriesandDataFrameconstructors not honoring the unit of atimedelta64[unit]dtype when constructing from floats or a mix of integers and floats, e.g.pd.Series([1.5, 90.0], dtype="timedelta64[s]")interpreted the numbers as nanoseconds and silently truncated them to zero instead of interpreting them as seconds (GH 63499)
Timezones#
Bug in
DatetimeIndexaddition with aDateOffsetthat has only timedelta components (e.g.DateOffset(hours=-2)) raisingValueErrornear DST transitions, while scalarTimestampaddition worked correctly (GH 28610)Bug in
DatetimeIndex.tz_convert()andDatetimeIndex.tz_localize()returning incorrect offsets for far-future dates (roughly 2088 to 2100) withzoneinfotimezones whose DST rule follows Ramadan, such asAfrica/CasablancaandAfrica/El_Aaiun(GH 65712)Bug in
Series.dt.tz_localize()andSeries.dt.tz_convert()(and theirDatetimeIndexcounterparts) returning incorrect results for non-nanosecond resolutions (e.g."s","ms","us") on timestamps before roughly 1677 (GH 66252)Bug in
Timestamp.to_julian_date()andDatetimeIndex.to_julian_date()returning the Julian date of the local wall clock for timezone-aware inputs instead of the underlying UTC instant (GH 54763)
Numeric#
Bug in
DataFrame.min(),DataFrame.max(),Series.min(), andSeries.max()on object-dtype data raisingTypeErrorwhen missing values were present alongside values that do not support comparison withfloat(e.g. strings or mixed-timezoneTimestampobjects) (GH 65500)Fixed bug in
read_excel()where having a column with mixture of numeric and boolean values will typecast the values based on the first appearance data type since 1==True and 0==False (GH 60088)Fixed bug in
DataFrame.idxmax()andDataFrame.idxmin()returning incorrect row labels for nullableUInt64columns containing missing values alongside values above2**53(GH 64478)Fixed bug in
DataFrame.idxmax()andDataFrame.idxmin()withaxis=1andskipna=Falsereturning incorrect column labels for extension array dtypes (e.g.BooleanDtype, nullable integer/float,ArrowDtype) (GH 56903)Fixed bug in
Series.clip()where passing a scalar numpy array (e.g.np.array(0)) would raise aTypeError(GH 59053)Fixed bug in
Series.idxmax(),Series.idxmin(),DataFrame.idxmax(), andDataFrame.idxmin()returning the label of a missing-value row when every non-missing value equals the dtype’s minimum (foridxmax) or maximum (foridxmin), e.g. a float column containing only-infand NaN (GH 64478)Fixed bug in
Series.mean()andSeries.sum()(and theirDataFramecounterparts) overflowing forfloat16dtypes instead of upcasting tofloat64(GH 43929)Fixed bug in
Series.skew()andSeries.kurt()(and theirDataFramecounterparts) returning0.0for degenerate distributions; these now returnNaN(GH 62864)Fixed bug in complex-dtype
Series.duplicated()andSeries.unique()(and related hashtable-backed methods) raisingTypeErrorwhen backed by aNumpyExtensionArray(GH 54761)Fixed bug where
DataFramearithmetic operations withSeriesdid not support the fill_value parameter(GH 61581)
Conversion#
Bug in
DataFrameconstructor raisingTypeErrorwhen given a list whose first element is a list-like dataclass (e.g. acollections.UserListsubclass); such elements are now treated as list-like rows (GH 41682)Bug in
DataFrameconstructor whereNaTin aTimedeltaIndexrow was incorrectly inferred asdatetime64instead oftimedelta64(GH 23985)Bug in
DataFrameconstructor where constructing from a list of uniform-dtype arrays (e.g. pyarrow,CategoricalDtype, nullable dtypes) lost the dtype (GH 49593)Bug in
pd.array()silently converting NaN to a nonsensical integer when given float data containing NaN and a NumPy integer dtype (GH 41724)Fixed
pandas.array()to preserve mask information when converting NumPy masked arrays, converting masked values to missing values (GH 63879)Fixed bug in
DataFrameconstructor where mutating the result could corrupt the sourceSeriesorIndexwhen built withdtype="str"andinfer_string=False(GH 63936)Fixed bug in
DataFrame.from_records()whereexcludewas ignored whendatawas an iterator andnrows=0(GH 63774)Fixed bug in
DataFrame.replace()andSeries.replace()raisingTypeErrorwhento_replacewasEllipsis(...) (GH 50373)Fixed bug in
DataFrame.to_dict()withorient="index"did not respect theintoargument in nested mappings (GH 65778)
Strings#
Bug in
DataFrame.replace()withregex=Truemutating the underlyingStringArraywhen the replacement value was not a string (GH 57733)Bug in
Series.memory_usage()withdeep=TrueraisingTypeErroron PyPy forstrdtype with Python storage (GH 46176)Bug in
Series.str.rsplit()andIndex.str.rsplit()silently accepting a compiled regex and returning incorrect results (GH 29633)Bug in
Series.str.split()withArrowDtypestringnot inferring regex for multi-character patterns whenregex=None, causing the pattern to be treated as a literal instead of a regular expression (GH 58321)Bug in
Series.unique(),Index.unique()andfactorize()on object dtype returning incorrect results when the values were not UTF-8 encodable, e.g. lone surrogates (GH 34550)
Interval#
Bug in
IntervalArrayandIntervalIndexconstructors unnecessarily upcasting sub-64-bit numeric dtypes (e.g.float32,int32) to 64-bit (GH 45412)Bug in
cut()and other operations building anIntervalIndexengine raisingTypeErroron 32-bit platforms when there were more than 100 intervals (GH 44075, GH 23440)
Indexing#
Bug in
TimedeltaIndexstring indexing using the resolution of the parsed value rather than the string, so keys like"720s"(an exact multiple of a minute) matched a minute-sized window instead of a second-sized one (GH 33603)Bug in
DataFrame.loc()andSeries.loc()replacing the index name with the key’s name when indexing with anIndex(GH 17110)Bug in
DataFrame.loc()raisingValueErrorwhen setting a row on aDataFramewith no columns and the label is not in the index (GH 17895)Bug in
DataFrame.loc()returning incorrect dtype when the column key is aslice(GH 63071)Bug in
Index.get_indexer()wheremethod="pad","backfill", or"nearest"returned incorrect results when the target containedNaTorNaNinstead of-1(GH 32572)Bug in
Series.loc()andDataFrame.loc()setitem-with-expansion silently corrupting a value just outside the integer dtype’s range (e.g.2**63forint64) on some platforms instead of keeping thefloat64result;infwas similarly affected, and both leaked aRuntimeWarning(GH 66394)Bug in
Series.loc()andDataFrame.loc()setitem-with-expansion widening adatetime64ortimedelta64column to microsecond resolution instead of keeping a coarser unit such assorms, even when the new value fit in it losslessly (GH 66402)Bugs in setitem-with-expansion when adding new rows failing to keep the original dtype in some cases (GH 32346, GH 15231, GH 47503, GH 6485, GH 25383, GH 52235, GH 17026, GH 56010)
Bug in
DataFrame.__getitem__()raisingInvalidIndexErrorwhen indexing with a tuple containing asliceon aDataFramewithMultiIndexcolumns (e.g.,df[:, "t1"]) (GH 26511)Bug in
DataFrame.__setitem__()silently keeping only the first column when assigning a 2D array to an existing column label, instead of raising as the new-column andDataFrame.loc()cases already did (GH 46544)Bug in
DataFrame.__setitem__()with a booleanDataFramemask raising a cryptic “cannot assign mismatch length to masked array”; it now raises aValueErrordescribing the mismatch between the number of values and the number ofTrueentries in the mask (GH 45593)Bug in
DataFrame.at()raisingTypeErrorwhen accessing aMultiIndexwith a partial date string on aDatetimeIndexlevel (GH 43395)Bug in
DataFrame.duplicated()returning an emptySerieswithout the DataFrame’s index when the DataFrame had no columns (GH 61191)Bug in
DataFrame.iloc()andSeries.iloc()setitem raisingValueError(“cannot set using a slice indexer with a different length than the value”) when assigning to a negative-step slice with an open-endedstartorstop(e.g.ser.iloc[::-2]) (GH 66100)Bug in
DataFrame.iloc()setitem raisingAttributeErrorwhen assigning aSeriesorIndexwith a nullable EA dtype (e.g.Int64,Float64,boolean) into a column with a NumPy dtype (GH 47776)Bug in
DataFrame.loc()raisingValueErrorwhen assigning a list of tuples to an object-dtype column with a boolean mask on a mixed-dtype DataFrame (GH 37629)Bug in
DataFrame.loc()raisingValueErrorwhen setting a row with a list-like value on a single-columnDataFramewithExtensionArraydtype (GH 44103)Bug in
DataFrame.loc()setitem-with-expansion writing the truncated string"n"(or raisingTypeError) into rows outside the indexer when adding a new column from a list of strings or booleans (GH 42099)Bug in
DataFrame.loc()with aMultiIndexreturning wrong results instead of raisingKeyErrorwhen passing string keys for numeric index levels (GH 60104)Bug in
DataFrame.mask()withinplace=Truewhere incorrect values were produced whenotherwas aSerieswithExtensionArrayvalues (GH 64635)Bug in
DataFrame.rename()andSeries.rename()not preserving nullable extension dtype (e.g.Int64,Float64) when relabeling index or column labels (GH 65315)Bug in
DataFrame.where()andDataFrame.mask()raisingTypeErrorwhencondis aSeriesandaxis=1(GH 58190)Bug in
DataFrame.xs()wheredrop_level=Falsewas ignored for fully specifiedMultiIndexkeys whenlevelwas not explicitly provided (GH 6507)Bug in
Index.get_indexer_non_unique()raisingZeroDivisionErrorinstead of returning an all-missing result when called on an empty index with a non-empty target (GH 54746)Bug in
Index.get_level_values()mishandling boolean, NA-like (np.nan,pd.NA,pd.NaT) and integer index names (GH 62169)Bug in
Index.get_loc()raisingKeyErrorwhen looking up a tuple in an object-dtypeIndexwith duplicates (GH 37800)Bug in
Index.insert()silently casting booleans to numeric when used with nullable numeric dtypes likeFloat64orInt64(GH 61709)Bug in
Index.take()wherefill_valuewas silently ignored and integer-dtype indexes raisedValueErrorinstead of filling with the provided value. Passingfill_value=Nonenow fills-1entries with the Index’s NA value (matching theExtensionArrayconvention); omitfill_valueto retain the previous behavior where negative indices wrap (GH 65210)Bug in
Index.where()andIndex.putmask()preservingnumpy.datetime64/numpy.timedelta64NaTscalars in the object-dtype result for mismatched-dtype inputs, instead of normalizing topandas.NaTasSeries.where()does (GH 55174)Bug in
MultiIndex.get_loc()returning a slice instead of an integer for a unique key when theMultiIndexcontained duplicates elsewhere, causing.locto return aSeriesinstead of a scalar (GH 42102)Bug in
RangeIndex.get_indexer()returning spurious matches for extreme integer targets (nearINT64_MINoruint64values aboveINT64_MAX) and failing to match genuine members of ranges spanning more thanINT64_MAX(GH 64148)Bug in
RangeIndex.memory_usage()andRangeIndex.nbytesraisingTypeErroron PyPy (GH 46176)Bug in
Series.where()andSeries.mask()raisingValueErrorwhenotheris a tuple on object-dtypeSeries(GH 37681)Bug in setitem (e.g.
Series.iloc()) silently storing wrong values when assigning a nullable orArrowDtypeextension array into a NumPy-dtype column that could not hold it losslessly, such as a negative value into an unsigned-integer column (-1became18446744073709551615) or a value overflowing a narrower float dtype (GH 47776)Bug in setitem on nullable masked arrays (
Int64,Float64,boolean, …) silently coercing list-like values that the equivalent scalar setitem would reject — e.g.arr[[0]] = ['1']parsed the string into the numeric dtype,arr[[0]] = [True]onInt64/Float64coerced the boolean to1, and an out-of-bounds value such asarr[[0]] = [1000]onInt8silently wrapped instead of raising (GH 45404)Fixed bug in
DataFrame.loc()where assigning an iterable to a single cell in anobjectdtype column incorrectly raised aValueError(GH 26333, GH 57962)Fixed bug in
DataFrame.loc()where assigning aSeriesto a subset of rows of one column upcast the dtype of other columns in a single-dtypeDataFrame(GH 66105)Fixed bug in
DataFrame.loc()where assigning with duplicate column names and new columns corrupted unrelated columns (GH 58317)Fixed segfault in
DataFrame.loc()when repeatedly adding new rows to an object-dtype-indexedDataFrame(GH 21968)
Missing#
Bug in
DataFrame.fillna()with a dict value raisingRecursionErrorwhen columns are aMultiIndexwith duplicate entries (GH 53498)Bug in
DataFrame.interpolate()andSeries.interpolate()withmethodin"index","values"or"time"raising when the index had anArrowDtypetimestamp or duration dtype; these now match the equivalentDatetimeIndexorTimedeltaIndex(GH 66338)Bug in
Series.combine_first()crashing when Series names areTimestampobjects (GH 65333)
MultiIndex#
Bug in
MultiIndexwhere pickling aDataFramewith adatetime64[ns]level raisedNotImplementedError(GH 63078)Bug in
DataFrame.loc()with aMultiIndexwhere using a tuple indexer with a scalar and a list (e.g.,(scalar, list)) did not drop the scalar-indexed level (GH 18631)Bug in
MultiIndex.get_loc()where looking up a tuple key containing a scalar inside anIntervalIndexlevel with overlapping intervals raisedKeyErroror returned incorrect results (GH 27456)Bug in
MultiIndex.set_levels()andMultiIndex.set_codes()raisingIndexErrorinstead of a clearValueErrorwhen passing an empty sequence withlevel=Noneor a list-likelevel(GH 16147)Bug in
MultiIndex.sortlevel()not raisingTypeErrorwhen sorting a level with incomparable types (e.g.,Timestampandstr) (GH 21136)Bug in
MultiIndex.union()raisingInvalidIndexErrorwhen combining levels containingdatetime.dateandTimestampvalues representing the same date (GH 61807)Constructing a
DataFramethat reindexes an integerMultiIndexonto a flat integer index now raises an informativeValueErrorinstead of a crypticValueError: Buffer dtype mismatch(GH 26460)MultiIndex.isin()now raises an informativeValueErrorwhen the values are not tuples matching the number of levels, instead of raising a crypticTypeErrororAssertionErroror silently returning incorrect results (GH 20252, GH 26622)
I/O#
read_csv()withengine="pyarrow"now raisesEmptyDataError(matching thecandpythonengines) instead of a crypticParserErrorreportingEmpty CSV file or blockwhen no columns can be parsed from the input (GH 66065)read_csv()withengine="pyarrow"now raisesValueErrorfor the unsupportedna_filter=Falseinstead of silently ignoring it (GH 66053)read_csv()withengine="pyarrow"now raises an informativeTypeErrorwhen passed a text-mode file handle (the engine requires a binary buffer) instead of a cryptica bytes-like object is requirederror (GH 66065)read_csv()withengine="pyarrow"now raises an informativeValueErrorfor a list-valuedheader(MultiIndex columns are not supported by this engine) instead of a crypticTypeError(GH 66059)read_csv()withmemory_map=Trueand an in-memory buffer (e.g.BytesIO) now raises a clearValueErrorinstead of a crypticUnsupportedOperation: fileno(GH 45630)read_json()withengine="pyarrow"now raisesValueErrorwhen passed an option the engine cannot apply – such astyp="series",convert_dates,keep_default_dates,date_unit,precise_float,convert_axes,encoding,encoding_errors,storage_options, an explicitcompression, or a non-ArrowDtypedtype– instead of silently ignoring it and returning an incorrect result (GH 66144)read_sql_table()now raises an informativeNotImplementedError(instead of one with no message) when passed a DBAPI connection such assqlite3, and reading from a URI string without a usablesqlalchemyinstall now raises a clearerImportError(GH 41237)read_sql()now raises an informativeDatabaseErrorexplaining that reading a table by name requires a SQLAlchemy connection when a bare table name is passed with a DBAPI connection (e.g.sqlite3), instead of a cryptic SQL syntax error (GH 54233)DataFrame.to_json()andSeries.to_json()now raise an informativeValueErrorinstead of a crypticOverflowError: Maximum recursion level reachedwhen a column contains an unsupported object type such aspathlib.Path(GH 36211)DataFrame.to_sql()now raises a clearerValueErrorwhen a non-stringdtypeis passed for a raw DB-API (e.g. sqlite3) connection (GH 61385)Fixed bug in
read_csv()withengine="pyarrow"wherenameswas silently ignored whenheaderwas also an integer;namesnow replaces the header row, extra leading columns form the index, and passing too manynamesraisesValueErroras with the other engines.usecolstogether withnamesand an integerheaderis not supported by this engine and now raises an informativeValueError(GH 65862)Fixed bug in
read_csv()withengine="pyarrow"where adefaultdictpassed asdtypedid not apply its default to columns not explicitly listed (GH 41574)Fixed bug in
read_csv()withengine="pyarrow"where an emptyusecols(e.g.usecols=[]) was ignored and returned all columns instead of an empty frame, unlike the other engines (GH 66056)Fixed bug in
read_csv()withengine="pyarrow"where passing tuples innamesproduced flat columns instead ofMultiIndexcolumns as with the other engines (GH 65862)Fixed bug in
read_csv()with thecengine where a quoted field containing an embedded NUL byte was silently truncated at the NUL under the default string dtype ordtype_backend="pyarrow"(GH 66415)Fixed bug in
read_csv()with thecengine where an embedded\rfollowed by a space in an unquoted field could cause an infinite re-parsing loop, producing spurious rows or a buffer overflow (GH 51141)Fixed bug in
read_excel()where usage ofskiprowscould lead to an infinite loop (GH 64027)Fixed bug in
read_excel()with theopenpyxlengine where reading a sheet set itsmax_rowandmax_columntoNoneon the workbook exposed throughExcelFile.book(GH 63010)Fixed bug where
read_html()parsed nested tables incorrectly when usinghtml5liborbs4flavors (GH 64524)Fixed bugs in
read_csv()withengine="pyarrow"where column names were handled inconsistently with the other engines: duplicated names were not de-duplicated to"x.1"-style names, empty header fields did not get"Unnamed: {i}"placeholder names, and an unnamedindex_colproduced an index named""instead of an unnamed index (GH 13017, GH 35211)Fixed bug in
read_csv()withengine="pyarrow"whereparse_datesdid not parse numeric-looking date columns or index columns, leaving them as integers or strings instead of datetimes (GH 34066)Fixed bug in
read_csv()withengine="pyarrow"where invalidsep,quotechar,escapechar, anddecimalarguments raised cryptic errors, or in the case ofquotechar=Nonewere silently ignored, instead of raising the same informative errors as the other engines (GH 66317)Fixed bug in
read_csv()withengine="pyarrow"where passing a scalar (non-dict)dtypetogether withindex_colraisedAttributeError; the scalardtypeis now also applied to the index column, matching the defaultcengine (GH 45801)Fixed memory leak in
read_csv()(GH 19941)Fixed memory leak in
DataFrame.to_json()andSeries.to_json()when serializingTimestampwith timezones (GH 54865)Fixed segfault in
DataFrame.to_json()andSeries.to_json()when serializing an object-dtypedatetime.dateordatetime.timedeltasubclass that carries a_valueattribute but no_cresoattribute (GH 65904)Fixed segfault when instantiating the internal
pandas._libs.parsers.TextReaderwith no arguments; it now raisesTypeError(GH 53131)Fixed
read_json()withlines=Trueandchunksizeto respectnrowswhen the requested row count is not a multiple of the chunk size (GH 64025)HDFStore.put()andHDFStore.append()now support storingSeriesandDataFramecolumns withPeriodDtypein both"fixed"and"table"formats (GH 41978)Bug in
DataFrame.__repr__()raisingTypeErrorfor a column with a NumPy structured dtype (e.g. produced byDataFrame.from_records()from a structuredndarray) (GH 55011)Bug in
DataFrame.__repr__()where horizontally truncated output could exceed the terminal width by up to 4 characters (GH 32461)Bug in
DataFrame.to_json()andSeries.to_json()withorient="table"silently dropping the timezone of columns with a fixed-offset timezone (e.g.datetime.timezone(timedelta(hours=1))), so the offset was lost on round-trip throughread_json()(GH 39537)Bug in
DataFrame.to_stata()raisingKeyErrorwhen column names require renaming andconvert_datesis specified for a different column (GH 60536)Bug in
DataFrame.to_string()whereformattersdict was applied to wrong columns when output was horizontally truncated viamax_cols(GH 35410)Fixed
read_json()withlines=Trueandnrows=0to return an empty DataFrame (GH 64025)DataFrame.to_hdf()now raises a clearNotImplementedErrorwhen writing a column orIndexof an unsupported extension dtype (such asIntervalDtype,SparseDtype, or the nullable integer/float/boolean dtypes), instead of a low-levelAttributeErroror PyTablesTypeError(GH 26144, GH 38305, GH 42070)read_hdf()can again read fixed-format files written by very old pandas versions (<=0.15.x) that stored afreqattribute on non-datetimelike indexes, which previously failed with aTypeErrororValueError(GH 33186)DataFrame.to_hdf()andHDFStorenow emit aUserWarningwhencomplibis passed withoutcomplevel; becausecompleveldefaults to0the data is written uncompressed, which previously happened silently (GH 29310)DataFrame.to_hdf()withformat="fixed"now compressesobjectdtype (e.g. string) columns whencomplib/complevelare given; previously the compression settings were silently ignored for these columns, producing much larger files (GH 45286)HDFStore.put(),HDFStore.append(), andDataFrame.to_hdf()now emit aUserWarninginstead of silently doing nothing when writing an emptyDataFrameorSerieswithformat='table'orappend=True(GH 13016)HDFStore.select()andread_hdf()now warn when a nestedwhereof the form"(A & B) | (C & D)"over indexed columns may return incorrect results because of an upstream PyTables bug, suggesting writing withindex=Falseor running theORbranches as separate queries (GH 50598)HDFStore.select()now raises a clearValueErrorwith a workaround, instead of an opaquetoo many inputserror, when awhereexpression has too many comparisons for a query against indexed columns (GH 39752)HDFStore.select()now raises an informativeNotImplementedErrorwhen awhereclause contains an arithmetic expression such as"(A % 3) == 0", instead of an opaque PyTablesTypeError; arithmetic inwherefilters is not supported (GH 41100)HDFStore.select(),HDFStore.select_as_coordinates(), andHDFStore.select_as_multiple()now raise an informativeNotImplementedErrorinstead of a crypticKeyErrorwhen a column selection such aswhere="columns=['A']"is used with any coordinate-based read (iterator=True,chunksize, or theselect_as_*methods); pass thecolumnsargument instead (GH 12953)Bug in
HDFStore.select()where awherequery on a categorical data column for a value that is not one of the categories incorrectly matched rows with missing (NaN) values (GH 22977)Fixed
MemoryErrorinHDFStore.select()when iterating large tables withchunksizeand nowherefilter (GH 15937)Fixed bug in
read_hdf()raising on files written by older pandas versions whosefreqindex attribute could not be decoded; thefreqis now dropped with a warning instead of corrupting the index (GH 35917)Fixed bug in
read_hdf()where a categorical column containing a category equal to thenan_repstring (e.g. the default"nan") raisedValueError: operands could not be broadcast togetherinstead of reading that category back asNaN(GH 21741)Fixed bug in
read_hdf()where a stringIndexorMultiIndexlevel did not round-trip missing values and the literal string"nan": a missing value was read back as"nan"and a literal"nan"was read back asNaN(GH 9604)Fixed bug in
DataFrame.to_hdf()andHDFStore.put()where writing an object to a key silently deleted any nested keys stored beneath it (GH 17267)Fixed bug in
DataFrame.to_hdf()raisingTypeErrorwhen the index had a non-tickDateOffsetfreq(e.g.DateOffset(years=1)) (GH 45790)Fixed bug in
DataFrame.to_hdf()withformat="table"where aTimedeltaIndexwas reconstructed as aPeriodIndex(whenfreqwas set) or an integerIndex(otherwise) on read-back (GH 21466)Fixed bug in
HDFStore.select()where awherecombining a row condition with an==/!=filter on a data column of more than 31 values (e.g."index>0 & col=big_list") silently returned extra rows that did not match the filter when read withiterator=Trueorchunksize(GH 12953)Fixed bug in
HDFStore.select()where an==/!=filter on a timezone-aware datetime data column of more than 31 values silently returned the wrong rows (typically none) on a plain read, because the timezone was dropped before the filter was applied (GH 12953)Fixed
DataFrame.to_hdf()andSeries.to_hdf()to round-trip aCategoricalIndexin both"fixed"and"table"formats; previously raisedAssertionError(GH 33909, GH 16118)Bug in
Series.to_json()withdate_format="iso"where a timezone-aware datetimeSerieswas serialized without the trailingZmarker, losing the timezone information that is retained for an equivalentDatetimeIndexorDataFramecolumn (GH 65744)Fixed bug in
read_hdf()where a store it had opened was left open if reading failed with an error other thanValueError,TypeError, orLookupError(e.g.AssertionError), so a subsequent attempt to reopen the file for writing raised “file is already opened” (GH 28430)Fixed bug in
DataFrame.to_parquet()(pyarrowengine) where a local file path was opened twice, once by pandas and again by pyarrow, wasting a syscall and silently truncating output to 0 bytes on filesystems that finalize a file’s contents on close (GH 65810)Fixed bug in
HDFStore.get_storer()where.shapereported a phantom row for a fixed-formatSeriesorDataFramestored with no rows (GH 37235)Fixed bug in
HDFStore.remove()where awhereclause selecting on more than 31 values (e.g."index in [...]") deleted the wrong rows instead of only the matching rows (GH 17567)Fixed bug in
HDFStore.select()where passingwhereas a list of conditions referencing caller-scope variables failed on Python 3.12+ due to PEP 709 inlining list comprehension stack frames (GH 64881)Fixed bug in
HDFStore.select()withformat="table"where reading a frame with a stringIndexcould crash with a bus error on strict-alignment platforms such as 32-bit ARM (GH 54396)Storing a
DataFrameorSerieswith aMultiIndexlevel named'index'viaHDFStore.put()orHDFStore.append()withformat='table'now raises a clearValueErrorinstead of an opaque reshape error (GH 6208)The
PerformanceWarningemitted byDataFrame.to_hdf()for object columns now names only the columns that cannot be mapped to a c-type, instead of every object column sharing the same block (GH 28460)Writing a
DataFramewithformat='table'and a column named'index'as adata_columnsentry (includingdata_columns=True) now raises a clearValueErrorinstead of an opaque reshape error (GH 41437)
Period#
Bug in
Periodconstructor where passingnp.str_objects would fail in Cython string parsing (GH 48974)Bug in
DatetimeIndex.to_period()where anchored offsetsYS,BYS,QS,BQS,BYE, andBQEproduced incorrect period frequencies, losing the month anchor (GH 36939)Bug in
Period.strftime()where unknown format directives (e.g."%Q") silently produced platform-dependent output and crashed the Python process on Windows; anInvalid format stringValueErroris now raised on all platforms (GH 53562)Bug in
Period.to_timestamp()andPeriodIndex.to_timestamp()returning incorrect timestamps when the target frequency normalized to nanoseconds (e.g."1ns") or when converting a nanosecondPeriodto a coarser target frequency (GH 63760)Bug in
Period.to_timestamp()andPeriodIndex.to_timestamp()withhow="end"losing nanosecond precision when the target frequency normalized to nanoseconds (e.g."1ns"); the target frequency is now also validated whenhow="end"(GH 63760)
Plotting#
Bug in
DataFrame.plot.hexbin()ignoringrcParams["image.cmap"]and always defaulting to"BuGn"when no colormap was specified (GH 31871)
Groupby/resample/rolling#
DataFrame.ewm()andSeries.ewm()now raise an informativeNotImplementedErrorinstead of a confusingAttributeErrorwhenagg/aggregateis passed an arbitrary callable (GH 41700)Bug in
PeriodIndexresampling to a finer frequency where aggregation methods returned the original values instead of aggregating, e.g.countreturned the data values rather than the number of observations per bin; empty bins now contain the method’s identity value (e.g.0forsuminstead ofNaN), consistent withDatetimeIndexresampling (GH 42763)Bug in
DataFrameGroupBy.agg()when there are no groups, multiple keys, andgroup_keys=False(GH 51445)Bug in
DataFrameGroupBy.agg()would operate on the group as a whole whenargsorkwargsare supplied for the providedfunc; now this method only operates on each Series of the group (GH 39169)Bug in
DataFrameGroupBy.apply()withas_index=Falsewhere applying on an emptyDataFramereturned inconsistent index metadata compared to non-empty results (GH 48135)Bug in
DataFrameGroupBy.cumprod(),DataFrameGroupBy.cummin(), andDataFrameGroupBy.cummax()(and Series variants) returningFloat64instead of preserving the nullable integer dtype (e.g.Int64) when the group key containsNA(GH 65550)Bug in
DataFrameGroupBy.idxmax(),DataFrameGroupBy.idxmin()(andSeriesvariants) withskipna=Falsereturning incorrect results when the input contained noNAvalues (GH 56903)Bug in
GroupBy.any()andGroupBy.all()returningNaNwithfloat64dtype for unobserved categorical groups on NumPybooldata instead of the boolean identity value withbooldtype (GH 65100)Bug in
GroupBy.quantile()returning incorrect results for groups containing a non-nullNaNvalue (e.g. from a pyarrow or masked float array), and returning the Unix epoch instead ofNaTfor all-NaTdatetime-like groups on some platforms (GH 64330)Bug in
Resampler.agg()raisingValueErrorwith a dict of aggregations when applied to aDataFrame.groupby()withas_index=False(GH 52397)Bug in
Rolling.corr()andRolling.cov()computing incorrect results on degenerate windows (GH 24019)Bug in
Rolling.corr()andRolling.cov()returningNaNfor all later windows once a window contained no valid pairs, e.g. due toNaNvalues (GH 65739)Bug in
Rolling.skew()andRolling.kurt()(and theirGroupBycounterparts) returning0.0and-3.0respectively for degenerate windows or groups; these now returnNaN(GH 62864)Bug in
Rolling.skew()andRolling.kurt()returningNaNfor low-variance windows (GH 62946)Bug in
Rolling.sum(),Rolling.mean(),Rolling.median(),Rolling.min(), andRolling.max()withmethod="table",engine="numba", andengine_kwargs={"parallel": True}could cause a segfault (GH 40454)Bug in
SeriesGroupBy.ohlc()ignoringas_index=False(GH 65140)Bug in
DataFrame.groupby()with aGrouperwithfreqraisingAttributeErrorwhen all grouping keys areNaT(GH 43486)Bug in
DataFrame.resample()andSeries.resample()with a timezone-naive index where using aDayfrequency (e.g."7D") produced different bin edges than the equivalentHourfrequency (e.g."168h"), and whereoriginandoffsetwere ignored (GH 44996, GH 62200)Bug in
DataFrame.resample()dropping the result index name when resamplingona column with a pyarrow-backed datetime or duration dtype (GH 59823)Bug in
Series.resample()andDataFrame.resample()where same-frequency resampling with monthly, quarterly, or annual frequencies bypassed aggregation, returning the original values instead of the aggregation result (GH 18553)
Reshaping#
concat()withkeysnow raises an informativeValueErrorinstead of anAssertionErrorwhen the concatenated objects do not all have the same number of index levels (GH 25413)DataFrame.pivot()andpivot()now raise an informativeKeyErrornaming the offending labels whenindex,columns, orvaluesare not columns of the frame, instead of a crypticTypeError(GH 35785)Bug in
concat()raisingInvalidIndexErrorwhenkeysor the concatenated objects’ index was an overlappingIntervalIndex(GH 64825)Bug in
merge()where merging on aMultiIndexcontainingNaNvalues mappedNaNkeys to the last level value instead ofNaN(GH 64492)Bug in
DataFrame.combine()raisingOverflowErrorwhen the combining function returned a value too large for the columns’ common integer dtype (e.g.2**64) instead of keeping the result (GH 66394)Bug in
DataFrame.melt()wherevar_namecolliding with anid_varscolumn orvalue_namesilently overwrote the affected column data instead of raising (GH 65654)Bug in
DataFrame.pivot_table()withmargins=TrueraisingTypeErrorwhenvalueshas anExtensionDtypethat cannot holdNA(e.g.IntervalDtypewith an integer subtype) and nocolumnswere specified (GH 55484)Bug in
DataFrame.select_dtypes()where a nullable extension dtype name such as"Int64"or"boolean"also selected numpy columns sharing the same scalar type; it now selects only columns of that extension dtype (GH 40234)Bug in
DataFrame.select_dtypes()where an interval spec giving a subtype but noclosedkeyword, such as"interval[int64]"orpd.IntervalDtype("int64"), selected no columns; it now selects every interval column with that subtype, for anyclosedvalue (GH 40234)Bug in
DataFrame.select_dtypes()where the string form of an Arrow dtype such as"int64[pyarrow]"selected no columns and"float64[pyarrow]"selected numpy float columns; an Arrow dtype string now selects only columns of that exact dtype (GH 59888)Bug in
Index.union()where the result could be unsorted when both inputs were monotonic increasing but disjoint, whensortwas notFalse(GH 54646)Fixed bug in
Series.sort_values()whereignore_index=Truehad no effect on an already-sorted Series (GH 65833)In
pivot_table(), whenvaluesis empty, the aggregation will be computed on a Series of all NA values (GH 46475)
Sparse#
Bug in
Series.mean()withskipna=Falseignoring missing values forSparseDtype-backedSeries(GH 65478)Bug in
Series.reindex()and alignment raising when extending a booleanSparseDtype-backedSeries; missing entries now upcast toobjectto match the dense behavior (GH 32119)Bug in
Series.sum(),Series.min(), andSeries.max()withskipna=Falseignoring missing values forSparseDtype-backedSeries(GH 65478)Bug in
SparseArray.astype()where converting a datetime64SparseArraywithNaTfill value to"Sparse[int64]"silently replaced the fill value with0instead ofiNaT(GH 49631)Bug in
SparseArray.mean()raising aTypeErrorwhen called with theskipnaargument (GH 65478)Bug in
SparseArray.sum()withskipna=FalsereturningNAfor a non-nullfill_valueand ignoring missing values under a nullfill_value(GH 65478)Bug in indexing a
SparseArraywith an out-of-bounds integer with the value of the length of the array returning the fill value instead of raising anIndexError(GH 64183).Bug in logical operators (
&,|,^) between aSparseDtype-backedSeriesand a differently-indexedSeriesraising an uninformative error instead of aligning and returning the expected result (GH 32119)
ExtensionArray#
api.extensions.register_extension_dtype()now raises an informativeTypeErrorat registration when theExtensionDtypesubclass does not define a stringnameattribute, instead of a bareAssertionErrorwhen the dtype is later used (GH 46093)Bug in
DataFrame.any()andDataFrame.all()withskipna=Falsenot propagatingpd.NAon numpy-nullable columns (boolean,Int*,UInt*,Float*);axis=0raisedValueErrorandaxis=1returned a concreteTrue/False(GH 65710)Bug in numpy ufuncs like
numpy.isnan()raisingTypeErroronSeriesorIndexbacked by PyArrow dtypes whenfuture.distinguish_nan_and_naisTrue(GH 62506)Fixed bug in
Series.apply()andSeries.map()where nullable integer dtypes were converted to float, causing precision loss for large integers; now the nullable dtype will be preserved (GH 63903).Fixed bug in
Series.cummax()andSeries.cummin()(and theirDataFramecounterparts) with floating-pointArrowDtypereturning a finite sentinel value instead of the correct running maximum/minimum (GH 66257)Fixed the
is_monotonic_increasingandis_monotonic_decreasingproperties to dispatch to the underlyingExtensionArrayimplementation (GH 65585)
Styler#
Fixed bug in
Styler.to_excel()where quoted strings in CSS properties were incorrectly lowercased, causing the exported Excel styling to use the wrong values; now quoted strings are left as-is (GH 63101)
Other#
Bug in
DataFrameconstructor where passing the sameIndexobject as bothindexandcolumnsshared a single object between the two axes, so mutating metadata such asnameson one would also change the other (GH 42934)Bug in
eval()andDataFrame.eval()where passing aSeriesorDataFrameasexprsilently parsed its (possibly truncated) repr instead of raising, producing a confusing error (GH 16289)Bug in
DataFrame.eval()where a duplicate column name was resolved to a single column (yielding aSeries), inconsistent withpandas.eval()usingresolvers=(df,)and withDataFrame.__getitem__(), which include every column with that label (GH 65588)Bug in
DataFrame.from_dict()where passing a dict of only scalar values raised aValueErrortelling users to pass anindex, even thoughDataFrame.from_dict()has noindexparameter; the message now points toorient='index'or theDataFrameconstructor (GH 25515)Bug in
DataFrame.select_dtypes()with anExtensionDtypesubclass such asArrowDtypeorDatetimeTZDtyperaisingTypeError, emitting a spuriousUserWarning, or selecting the wrong columns; passing such a class now selects every column whose dtype is an instance of that class (GH 65366)Bug in
Series.transform()andDataFrame.transform()where passing a list of duplicate function names did not raiseerrors.SpecificationError(GH 54929)Bug in
register_optionwhere registering an option whose name was a prefix of an existing option (e.g."a.b"when"a.b.c"was already registered) silently overwrote the existing option’s namespace instead of raising (GH 29242)