What’s new in 3.0.0 (January 21, 2026)#

These are the changes in pandas 3.0.0. See Release notes for a full changelog including other versions of pandas.

Note

The pandas 3.0 release removed a lot of functionality that was deprecated in previous releases (see below for an overview). It is recommended to first upgrade to pandas 2.3 and to ensure your code is working without warnings, before upgrading to pandas 3.0.

Enhancements#

Dedicated string data type by default#

Historically, pandas represented string columns with NumPy object data type. This representation has numerous problems: it is not specific to strings (any Python object can be stored in an object-dtype array, not just strings) and it is often not very efficient (both performance wise and for memory usage).

Starting with pandas 3.0, a dedicated string data type is enabled by default (backed by PyArrow under the hood, if installed, otherwise falling back to being backed by NumPy object-dtype). This means that pandas will start inferring columns containing string data as the new str data type when creating pandas objects, such as in constructors or IO functions.

Old behavior:

>>> ser = pd.Series(["a", "b"])
0    a
1    b
dtype: object

New behavior:

>>> ser = pd.Series(["a", "b"])
0    a
1    b
dtype: str

The string data type that is used in these scenarios will mostly behave as NumPy object would, including missing value semantics and general operations on these columns.

The main characteristic of the new string data type:

  • Inferred by default for string data (instead of object dtype)

  • The str dtype can only hold strings (or missing values), in contrast to object dtype. (setitem with non string fails)

  • The missing value sentinel is always NaN (np.nan) and follows the same missing value semantics as the other default dtypes.

Those intentional changes can have breaking consequences, for example when checking for the .dtype being object dtype or checking the exact missing value sentinel. See the Migration guide for the new string data type (pandas 3.0) for more details on the behaviour changes and how to adapt your code to the new default.

Consistent copy/view behaviour with Copy-on-Write#

The new “copy-on-write” behaviour in pandas 3.0 brings changes in behavior in how pandas operates with respect to copies and views. A summary of the changes:

  1. The result of any indexing operation (subsetting a DataFrame or Series in any way, i.e. including accessing a DataFrame column as a Series) or any method returning a new DataFrame or Series, always behaves as if it were a copy in terms of user API.

  2. As a consequence, if you want to modify an object (DataFrame or Series), the only way to do this is to directly modify that object itself.

The main goal of this change is to make the user API more consistent and predictable. There is now a clear rule: any subset or returned series/dataframe always behaves as a copy of the original, and thus never modifies the original (before pandas 3.0, whether a derived object would be a copy or a view depended on the exact operation performed, which was often confusing).

Because every single indexing step now behaves as a copy, this also means that “chained assignment” (updating a DataFrame with multiple setitem steps) will stop working. Because this now consistently never works, the SettingWithCopyWarning is removed, and defensive .copy() calls to silence the warning are no longer needed.

The new behavioral semantics are explained in more detail in the user guide about Copy-on-Write.

A secondary goal is to improve performance by avoiding unnecessary copies. As mentioned above, every new DataFrame or Series returned from an indexing operation or method behaves as a copy, but under the hood pandas will use views as much as possible, and only copy when needed to guarantee the “behaves as a copy” behaviour (this is the actual “copy-on-write” mechanism used as an implementation detail).

Some of the behaviour changes described above are breaking changes in pandas 3.0. When upgrading to pandas 3.0, it is recommended to first upgrade to pandas 2.3 to get deprecation warnings for a subset of those changes. The migration guide explains the upgrade process in more detail.

Setting the option mode.copy_on_write no longer has any impact. The option is deprecated and will be removed in pandas 4.0.

Initial support for pd.col() syntax to create expressions#

This release introduces col() to refer to a DataFrame column by name and build up expressions.

This can be used as a simplified syntax to create callables for use in methods such as DataFrame.assign(). In practice, where you would have to use a lambda function before, you can now use pd.col() instead.

For example, if you have a dataframe

In [1]: df = pd.DataFrame({'a': [1, 1, 2], 'b': [4, 5, 6]})

and you want to create a new column 'c' by summing 'a' and 'b', then instead of

In [2]: df.assign(c = lambda df: df['a'] + df['b'])
Out[2]: 
   a  b  c
0  1  4  5
1  1  5  6
2  2  6  8

you can now write:

In [3]: df.assign(c = pd.col('a') + pd.col('b'))
Out[3]: 
   a  b  c
0  1  4  5
1  1  5  6
2  2  6  8

The expression object returned by col() supports all standard operators (like +, -, *, /, etc.) and all Series methods and namespaces (like pd.col("name").sum(), pd.col("name").str.upper(), etc.).

Currently, the pd.col() syntax can be used in any place which accepts a callable that takes the calling DataFrame as first argument and returns a Series, like lambda df: df[col_name]. This includes DataFrame.assign(), DataFrame.loc(), and getitem/setitem.

It is expected that the support for pd.col() will be expanded to more methods in future releases.

Support for the Arrow PyCapsule Interface#

The Arrow C data interface allows moving data between different DataFrame libraries through the Arrow format, and is designed to be zero-copy where possible. In Python, this interface is exposed through the Arrow PyCapsule Protocol.

DataFrame and Series now support the Arrow PyCapsule Interface for both export and import of data (GH 56587, GH 63208, GH 59518, GH 59631).

The dedicated DataFrame.from_arrow() and Series.from_arrow() methods are added to import any Arrow-compatible data object into a pandas object through the interface.

For export, the DataFrame and Series implement the C stream interface (__arrow_c_stream__) method.

Those methods currently rely on pyarrow to convert the tabular object in Arrow format to/from pandas.

Updated deprecation policy#

pandas 3.0.0 updates the deprecation policy to clarify which deprecation warnings will be issued, using a new 3-stage policy: using DeprecationWarning initially, then switching to FutureWarning for broader visibility in the last minor version before the next major release, and then removal of the deprecated functionality in the major release. This was done to give downstream packages more time to adjust to pandas deprecations, which should reduce the amount of warnings that a user gets from code that isn’t theirs. See PDEP 17 for more details.

All warnings for upcoming changes in pandas will have the base class pandas.errors.PandasChangeWarning. Users may also use the following subclasses to control warnings.

Deprecations added in 3.x using pandas.errors.Pandas4Warning will initially inherit from pandas.errors.PandasDeprecationWarning. In the last minor release of the 3.x series, these deprecations will switch to inherit from pandas.errors.PandasFutureWarning for broader visibility.

Other enhancements#

I/O:

Groupby/resample/rolling:

Reshaping:

Missing:

Numeric:

Strings:

Datetimelike:

  • Easter has gained a new constructor argument method which specifies the method used to calculate Easter — for example, Orthodox Easter (GH 61665)

  • Holiday constructor argument days_of_week will raise a ValueError when type is something other than None or tuple (GH 61658)

  • Holiday has gained the constructor argument and field exclude_dates to exclude specific datetimes from a custom holiday calendar (GH 54382)

  • Added half-year offset classes HalfYearBegin, HalfYearEnd, BHalfYearBegin and BHalfYearEnd (GH 60928)

  • Improved deprecation message for offset aliases (GH 60820)

  • Multiplying two DateOffset objects will now raise a TypeError instead of a RecursionError (GH 59442)

Indexing:

Styler / output formatting:

Typing:

Plotting:

ExtensionArray:

Other:

Packaging:

  • Switched wheel upload to PyPI Trusted Publishing (OIDC) for release-tag pushes in wheels.yml. (GH 61718)

  • Wheels are now available for Windows ARM64 architecture (GH 61462)

  • Wheels are now available for free-threading Python builds on Windows (in addition to the other platforms) (GH 61463)

Notable bug fixes#

These are bug fixes that might have notable behavior changes.

Improved behavior in groupby for observed=False#

A number of bugs have been fixed due to improved handling of unobserved groups. All remarks in this section equally impact SeriesGroupBy. (GH 55738)

In previous versions of pandas, a single grouping with DataFrameGroupBy.apply() or DataFrameGroupBy.agg() would pass the unobserved groups to the provided function, resulting correctly in 0 below.

In [4]: df = pd.DataFrame(
   ...:     {
   ...:         "key1": pd.Categorical(list("aabb"), categories=list("abc")),
   ...:         "key2": [1, 1, 1, 2],
   ...:         "values": [1, 2, 3, 4],
   ...:     }
   ...: )
   ...: 

In [5]: df
Out[5]: 
  key1  key2  values
0    a     1       1
1    a     1       2
2    b     1       3
3    b     2       4

In [6]: gb = df.groupby("key1", observed=False)

In [7]: gb[["values"]].apply(lambda x: x.sum())
Out[7]: 
      values
key1        
a          3
b          7
c          0

However this was not the case when using multiple groupings, resulting in NaN below.

In [1]: gb = df.groupby(["key1", "key2"], observed=False)
In [2]: gb[["values"]].apply(lambda x: x.sum())
Out[2]:
           values
key1 key2
a    1        3.0
     2        NaN
b    1        3.0
     2        4.0
c    1        NaN
     2        NaN

Now using multiple groupings will also pass the unobserved groups to the provided function.

In [8]: gb = df.groupby(["key1", "key2"], observed=False)

In [9]: gb[["values"]].apply(lambda x: x.sum())
Out[9]: 
           values
key1 key2        
a    1          3
     2          0
b    1          3
     2          4
c    1          0
     2          0

Similarly:

These improvements also fixed certain bugs in groupby:

Backwards incompatible API changes#

Datetime/timedelta resolution inference#

Prior to pandas 3.0, whenever converting a sequence of of strings, stdlib datetime objects, np.datetime64 objects, or integers to a datetime64 / timedelta64 dtype, this would always have resulted in nanosecond resolution (or raised an out-of-bounds error). Now it performs inference on the appropriate resolution (a.k.a. unit) for the output dtype. This affects both the generric constructors (Series, DataFrame, Index, DatetimeIndex) as specific conversion or creation functions (to_datetime(), to_timedelta(), date_range(), timedelta_range(), Timestamp, Timedelta).

The general rules for the various types of input:

  • The new default resolution when parsing strings is microseconds, falling back to nanoseconds when the precision of the string requires it.

  • The resolution of the input is preserved for stdlib datetime objects (i.e. microseconds) or np.datetime64/np.timedelta64 objects (i.e. the unit, capped to the supported range of seconds to nanoseconds).

  • For integer input, the resolution how the integer value is interpreted is used as the resulting resolution (or capped to the supported range of seconds to nanoseconds).

For example, the following would always have given nanosecond resolution previously, but now infer:

# parsing strings
In [10]: print(pd.to_datetime(["2024-03-22 11:36"]).dtype)
datetime64[us]

# converting integers
In [11]: print(pd.to_datetime([0], unit="s").dtype)
datetime64[s]

# converting stdlib datetime object
In [12]: dt = pd.Timestamp("2024-03-22 11:36").to_pydatetime()

In [13]: print(pd.to_datetime([dt]).dtype)
datetime64[us]

# the same when inferring a datetime dtype in the generic constructors
In [14]: print(pd.Series([dt]).dtype)
datetime64[us]

# converting numpy objects
In [15]: print(pd.Series([np.datetime64("2024-03-22", "ms")]).dtype)
datetime64[ms]

Similar when passed a sequence of np.datetime64 objects, the resolution of the passed objects will be retained (or for lower-than-second resolution, second resolution will be used).

When parsing strings, the default is now microseconds (which also impacts I/O methods reading from text files, such as read_csv() and read_json()). Except when the string has nanosecond precision, in which case nanosecond resolution is used:

In [16]: print(pd.to_datetime(["2024-03-22 11:43:01.123"]).dtype)
datetime64[us]

In [17]: print(pd.to_datetime(["2024-03-22 11:43:01.123456"]).dtype)
datetime64[us]

In [18]: print(pd.to_datetime(["2024-03-22 11:43:01.123456789"]).dtype)
datetime64[ns]

This is also a change for the Timestamp constructor with a string input, which in version 2.x.y could give second or millisecond unit (GH 52653).

Warning

Many users will now get “datetime64[us]” dtype data in cases when they used to get “datetime64[ns]”. For most use cases they should not notice a difference. One big exception is converting to integers, which will give integers 1000x smaller.

When converting datetime-like data to integers, it is recommended to avoid astype("int64") to make your code agnostic to the exact unit, or ensure the desired unit with as_unit() before casting.

See From timestamps to epoch for more details.

concat() no longer ignores sort when all objects have a DatetimeIndex#

When all objects passed to concat() have a DatetimeIndex, passing sort=False will now result in the non-concatenation axis not being sorted. Previously, the result would always be sorted along the non-concatenation axis even when sort=False is passed. (GH 57335)

If you do not specify the sort argument, pandas will continue to return a sorted result but this behavior is deprecated and you will receive a warning. In order to make this less noisy for users, pandas checks if not sorting would impact the result and only warns when it would. This check can be expensive, and users can skip the check by explicitly specifying sort=True or sort=False.

This deprecation can also impact pandas’ internal usage of concat(). Here cases where concat() was sorting a DatetimeIndex but not other indexes are considered bugs and have been fixed as noted below. However it is possible some have been missed. In order to be cautious here, pandas has not added sort=False to any internal calls where we believe behavior should not change. If we have missed something, users will not experience a behavior change but they will receive a warning about concat() even though they are not directly calling this function. If this does occur, we ask users to open an issue so that we may address any potential behavior changes.

In [19]: idx1 = pd.date_range("2025-01-02", periods=3, freq="h")

In [20]: df1 = pd.DataFrame({"a": [1, 2, 3]}, index=idx1)

In [21]: df1
Out[21]: 
                     a
2025-01-02 00:00:00  1
2025-01-02 01:00:00  2
2025-01-02 02:00:00  3

In [22]: idx2 = pd.date_range("2025-01-01", periods=3, freq="h")

In [23]: df2 = pd.DataFrame({"b": [1, 2, 3]}, index=idx2)

In [24]: df2
Out[24]: 
                     b
2025-01-01 00:00:00  1
2025-01-01 01:00:00  2
2025-01-01 02:00:00  3

Old behavior

In [3]: pd.concat([df1, df2], axis=1, sort=False)
Out[3]:
                       a    b
2025-01-01 00:00:00  NaN  1.0
2025-01-01 01:00:00  NaN  2.0
2025-01-01 02:00:00  NaN  3.0
2025-01-02 00:00:00  1.0  NaN
2025-01-02 01:00:00  2.0  NaN
2025-01-02 02:00:00  3.0  NaN

New behavior

In [25]: pd.concat([df1, df2], axis=1, sort=False)
Out[25]: 
                       a    b
2025-01-02 00:00:00  1.0  NaN
2025-01-02 01:00:00  2.0  NaN
2025-01-02 02:00:00  3.0  NaN
2025-01-01 00:00:00  NaN  1.0
2025-01-01 01:00:00  NaN  2.0
2025-01-01 02:00:00  NaN  3.0

Cases where pandas’ internal usage of concat() resulted in inconsistent sorting that are now fixed in this release are as follows.

Changed behavior in DataFrame.value_counts() and DataFrameGroupBy.value_counts() when sort=False#

In previous versions of pandas, DataFrame.value_counts() with sort=False would sort the result by row labels (as was documented). This was nonintuitive and inconsistent with Series.value_counts() which would maintain the order of the input. Now DataFrame.value_counts() will maintain the order of the input. (GH 59745)

In [26]: df = pd.DataFrame(
   ....:     {
   ....:         "a": [2, 2, 2, 2, 1, 1, 1, 1],
   ....:         "b": [2, 1, 3, 1, 2, 3, 1, 1],
   ....:     }
   ....: )
   ....: 

In [27]: df
Out[27]: 
   a  b
0  2  2
1  2  1
2  2  3
3  2  1
4  1  2
5  1  3
6  1  1
7  1  1

Old behavior

In [3]: df.value_counts(sort=False)
Out[3]:
a  b
1  1    2
   2    1
   3    1
2  1    2
   2    1
   3    1
Name: count, dtype: int64

New behavior

In [28]: df.value_counts(sort=False)
Out[28]: 
a  b
2  2    1
   1    2
   3    1
1  2    1
   3    1
   1    2
Name: count, dtype: int64

This change also applies to DataFrameGroupBy.value_counts(). Here, there are two options for sorting: one sort passed to DataFrame.groupby() and one passed directly to DataFrameGroupBy.value_counts(). The former will determine whether to sort the groups, the latter whether to sort the counts. All non-grouping columns will maintain the order of the input within groups.

Old behavior

In [5]: df.groupby("a", sort=True).value_counts(sort=False)
Out[5]:
a  b
1  1    2
   2    1
   3    1
2  1    2
   2    1
   3    1
dtype: int64

New behavior

In [29]: df.groupby("a", sort=True).value_counts(sort=False)
Out[29]: 
a  b
1  2    1
   3    1
   1    2
2  2    1
   3    1
   1    2
Name: count, dtype: int64

Changed behavior of pd.offsets.Day to always represent calendar-day#

In previous versions of pandas, offsets.Day represented a fixed span of 24 hours, disregarding Daylight Savings Time transitions. It now consistently behaves as a calendar-day, preserving time-of-day across DST transitions. (GH 61985)

Old behavior

In [5]: ts = pd.Timestamp("2025-03-08 08:00", tz="US/Eastern")
In [6]: ts + pd.offsets.Day(1)
Out[3]: Timestamp('2025-03-09 09:00:00-0400', tz='US/Eastern')

New behavior

In [30]: ts = pd.Timestamp("2025-03-08 08:00", tz="US/Eastern")

In [31]: ts + pd.offsets.Day(1)
Out[31]: Timestamp('2025-03-09 08:00:00-0400', tz='US/Eastern')

This change fixes a long-standing bug in date_range() (GH 51716, GH 35388), but causes several small behavior differences as collateral:

  • pd.offsets.Day(n) no longer compares as equal to pd.offsets.Hour(24*n)

  • offsets.Day no longer supports division

  • Timedelta no longer accepts Day objects as inputs

  • tseries.frequencies.to_offset() on a Timedelta object returns an offsets.Hour object in cases where it used to return a Day object.

  • Adding or subtracting a scalar from a timezone-aware DatetimeIndex with a Day freq no longer preserves that freq attribute.

  • Adding or subtracting a Day with a Timedelta is no longer supported.

  • Adding or subtracting a Day offset to a timezone-aware Timestamp or datetime-like may lead to an ambiguous or non-existent time, which will raise.

Changed treatment of NaN values in pyarrow and numpy-nullable floating dtypes#

Previously, when dealing with a nullable dtype (e.g. Float64Dtype or int64[pyarrow]), NaN was treated as interchangeable with NA in some circumstances but not others. This was done to make adoption easier, but caused some confusion (GH 32265). In 3.0, this behaviour is made consistent to by default treat NaN as equivalent to NA in all cases.

By default, NaN can be passed to constructors, __setitem__, __contains__ and will be treated the same as NA. The only change users will see is that arithmetic and np.ufunc operations that previously introduced NaN entries produce NA entries instead.

Old behavior:

# NaN in input gets converted to NA
In [1]: ser = pd.Series([0, np.nan], dtype=pd.Float64Dtype())
In [2]: ser
Out[2]:
0     0.0
1    <NA>
dtype: Float64
# NaN produced by arithmetic (0/0) remained NaN
In [3]: ser / 0
Out[3]:
0     NaN
1    <NA>
dtype: Float64
# the NaN value is not considered as missing
In [4]: (ser / 0).isna()
Out[4]:
0    False
1     True
dtype: bool

New behavior:

In [32]: ser = pd.Series([0, np.nan], dtype=pd.Float64Dtype())

In [33]: ser
Out[33]: 
0     0.0
1    <NA>
dtype: Float64

In [34]: ser / 0
Out[34]: 
0    <NA>
1    <NA>
dtype: Float64

In [35]: (ser / 0).isna()
Out[35]: 
0    True
1    True
dtype: bool

In the future, the intention is to consider NaN and NA as distinct values, and an option to control this behaviour is added in 3.0 through pd.options.future.distinguish_nan_and_na. When enabled, NaN is always considered distinct and specifically as a floating-point value. As a consequence, it cannot be used with integer dtypes.

Old behavior:

In [2]: ser = pd.Series([1, np.nan], dtype=pd.Float64Dtype())
In [3]: ser[1]
Out[3]: <NA>

New behavior:

In [36]: with pd.option_context("future.distinguish_nan_and_na", True):
   ....:     ser = pd.Series([1, np.nan], dtype=pd.Float64Dtype())
   ....:     print(ser[1])
   ....: 
nan

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.

With "future.distinguish_nan_and_na" enabled, ser.to_numpy() (and frame.values and np.asarray(obj)) will convert to object dtype if NA entries are present, where before they would coerce to NaN. To retain a float numpy dtype, explicitly pass na_value=np.nan to Series.to_numpy().

Note that the option is experimental and subject to change in future releases.

The __module__ attribute now points to public modules#

The __module__ attribute on functions and classes in the public API has been updated to refer to the preferred public module from which to access the object, rather than the module in which the object happens to be defined (GH 55178).

This produces more informative displays in the Python console for classes, e.g., instead of <class 'pandas.core.frame.DataFrame'> you now see <class 'pandas.DataFrame'>, and in interactive tools such as IPython, e.g., instead of <function pandas.io.parsers.readers.read_csv(...)> you now see <function pandas.read_csv(...)>.

This may break code that relies on the previous __module__ values (e.g. doctests inspecting the type() of a DataFrame object).

Increased minimum version for Python#

pandas 3.0.0 supports Python 3.11 and higher.

Increased minimum versions for dependencies#

Some minimum supported versions of dependencies were updated. The following required dependencies were updated:

Package

New Minimum Version

numpy

1.26.0

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

New Minimum Version

adbc-driver-postgresql

1.2.0

adbc-driver-sqlite

1.2.0

mypy (dev)

1.9.0

beautifulsoup4

4.12.3

bottleneck

1.4.2

fastparquet

2024.11.0

fsspec

2024.10.0

hypothesis

6.116.0

gcsfs

2024.10.0

Jinja2

3.1.5

lxml

5.3.0

Jinja2

3.1.3

matplotlib

3.9.3

numba

0.60.0

numexpr

2.10.2

qtpy

2.4.2

openpyxl

3.1.5

psycopg2

2.9.10

pyarrow

13.0.0

pymysql

1.1.1

pyreadstat

1.2.8

pytables

3.10.1

python-calamine

0.3.0

pytz

2024.2

s3fs

2024.10.0

SciPy

1.14.1

sqlalchemy

2.0.36

xarray

2024.10.0

xlsxwriter

3.2.0

zstandard

0.23.0

See Dependencies and Optional dependencies for more.

pytz now an optional dependency#

pandas now uses zoneinfo from the standard library as the default timezone implementation when passing a timezone string to various methods. (GH 34916)

Old behavior:

In [1]: ts = pd.Timestamp(2024, 1, 1).tz_localize("US/Pacific")
In [2]: ts.tz
<DstTzInfo 'US/Pacific' LMT-1 day, 16:07:00 STD>

New behavior:

In [37]: ts = pd.Timestamp(2024, 1, 1).tz_localize("US/Pacific")

In [38]: ts.tz
Out[38]: zoneinfo.ZoneInfo(key='US/Pacific')

pytz timezone objects are still supported when passed directly, but they will no longer be returned by default from string inputs. Moreover, pytz is no longer a required dependency of pandas, but can be installed with the pip extra pip install pandas[timezone].

Additionally, pandas no longer throws pytz exceptions for timezone operations leading to ambiguous or nonexistent times. These cases will now raise a ValueError.

Other API changes#

  • 3rd party py.path objects are no longer explicitly supported in IO methods. Use pathlib.Path objects instead (GH 57091)

  • read_table()’s parse_dates argument defaults to None to improve consistency with read_csv() (GH 57476)

  • Period.to_timestamp() and PeriodIndex.to_timestamp() now give microsecond-unit objects when possible, and nanosecond-unit objects in other cases. This affects the actual value of Period.end_time() and PeriodIndex.end_time() (GH 56164)

  • All classes inheriting from builtin tuple (including types created with collections.namedtuple()) are now hashed and compared as builtin tuple during indexing operations (GH 57922)

  • Made dtype a required argument in ExtensionArray._from_sequence_of_strings() (GH 56519)

  • Passing a Series input to json_normalize() will now retain the Series Index, previously output had a new RangeIndex (GH 51452)

  • Pickle and HDF (.h5) files created with Python 2 are no longer explicitly supported (GH 57387)

  • Pickled objects from pandas version less than 1.0.0 are no longer supported (GH 57155)

  • Removed Index.sort() which always raised a TypeError. This attribute is not defined and will raise an AttributeError (GH 59283)

  • Unused dtype argument has been removed from the MultiIndex constructor (GH 60962)

  • Updated DataFrame.to_excel() so that the output spreadsheet has no styling. Custom styling can still be done using Styler.to_excel() (GH 54154)

  • When comparing the indexes in testing.assert_series_equal(), check_exact defaults to True if an Index is of integer dtype. (GH 57386)

  • Index set operations (like union or intersection) will now ignore the dtype of an empty RangeIndex or empty Index with object dtype when determining the dtype of the resulting Index (GH 60797)

  • 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 (GH 55782)

  • Series “flex” methods like Series.add() no longer allow passing a DataFrame for other; use the DataFrame reversed method instead (GH 46179)

  • date_range() and 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 (GH 59031)

  • CategoricalIndex.append() no longer attempts to cast different-dtype indexes to the caller’s dtype (GH 41626)

  • ExtensionDtype.construct_array_type() is now a regular method instead of a classmethod (GH 58663)

  • Arithmetic operations between a Series, Index, or 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 (GH 62552)

  • Comparison operations between Index and Series now consistently return Series regardless of which object is on the left or right (GH 36759)

  • NumPy functions like np.isinf that return a bool dtype when called on a Index object now return a bool-dtype Index instead of np.ndarray (GH 52676)

  • Methods that can operate in-place (replace(), fillna(), ffill(), bfill(), interpolate(), where(), mask(), clip()) now return the modified DataFrame or Series (self) instead of None when inplace=True (GH 63207)

  • All Index constructors now copy numpy.ndarray and ExtensionArray inputs by default when copy=None, consistent with Series behavior (GH 63388)

Deprecations#

Copy keyword#

The copy keyword argument in the following methods is deprecated and will be removed in a future version. (GH 57347)

Copy-on-Write utilizes a lazy copy mechanism that defers copying the data until necessary. Use .copy to trigger an eager copy. The copy keyword has no effect starting with 3.0, so it can be safely removed from your code.

Other Deprecations#

Removal of prior version deprecations/changes#

Enforced deprecation of aliases M, Q, Y, etc. in favour of ME, QE, YE, etc. for offsets#

Renamed the following offset aliases (GH 57986):

offset

removed alias

new alias

MonthEnd

M

ME

BusinessMonthEnd

BM

BME

SemiMonthEnd

SM

SME

CustomBusinessMonthEnd

CBM

CBME

QuarterEnd

Q

QE

BQuarterEnd

BQ

BQE

YearEnd

Y

YE

BYearEnd

BY

BYE

Other Removals#

Performance improvements#

Bug fixes#

Categorical#

Datetimelike#

Timedelta#

  • Accuracy improvement in Timedelta.to_pytimedelta() to round microseconds consistently for large nanosecond based Timedelta (GH 57841)

  • Bug in Timedelta constructor failing to raise when passed an invalid keyword (GH 53801)

  • Bug in DataFrame.cumsum() which was raising IndexError if dtype is timedelta64[ns] (GH 57956)

  • Bug in adding or subtracting a Timedelta object with non-nanosecond unit to a python datetime.datetime object giving incorrect results; this now works correctly for Timedeltas inside the datetime.timedelta implementation bounds (GH 53643)

  • Bug in multiplication operations with timedelta64 dtype failing to raise TypeError when multiplying by bool objects or dtypes (GH 58054)

  • Bug in multiplication operations with timedelta64 dtype incorrectly raising when multiplying by numpy-nullable dtypes or pyarrow integer dtypes (GH 58054)

  • Bug in the Series constructor not honoring the unit of the timedelta64[unit] dtype when constructing a timedelta series from integers, e.g. pd.Series([0, 1, 2], dtype="timedelta64[s]") still interpreted the numbers as nanoseconds instead of seconds. Now it will interpret the passed integers according to the unit of the specified dtype (GH 48312, GH 52457)

Timezones#

  • Bug in DatetimeIndex.union(), DatetimeIndex.intersection(), and DatetimeIndex.symmetric_difference() changing timezone to UTC when merging two DatetimeIndex objects with the same timezone but different units (GH 60080)

  • Bug in Series.dt.tz_localize() with a timezone-aware ArrowDtype incorrectly converting to UTC when tz=None (GH 61780)

  • Fixed bug in date_range() where tz-aware endpoints with calendar offsets (e.g. "MS") failed on DST fall-back. These now respect ambiguous/ nonexistent. (GH 52908)

Numeric#

Conversion#

Strings#

Interval#

Indexing#

  • Bug in DataFrame.__getitem__() when slicing a DataFrame with many rows raised an OverflowError (GH 59531)

  • Bug in DataFrame.__setitem__() on an empty DataFrame with a tuple corrupting the frame (GH 54385)

  • Bug in DataFrame.from_records() throwing a ValueError when passed an empty list in index (GH 58594)

  • Bug in DataFrame.loc() and DataFrame.iloc() returning incorrect dtype when selecting from a DataFrame with mixed data types. (GH 60600)

  • Bug in DataFrame.loc() with inconsistent behavior of loc-set with 2 given indexes to Series (GH 59933)

  • Bug in Index.equals() when comparing between Series with string dtype Index (GH 61099)

  • Bug in Index.get_indexer() and similar methods when NaN is located at or after position 128 (GH 58924)

  • Bug in MultiIndex.insert() when a new value inserted to a datetime-like level gets cast to NaT and fails indexing (GH 60388)

  • Bug in Series.__setitem__() when assigning boolean series with boolean indexer will raise LossySetitemError (GH 57338)

  • Bug in indexing obj.loc[start:stop] with a DatetimeIndex and Timestamp endpoints with higher resolution than the index (GH 63262)

  • Bug in printing Index.names and MultiIndex.levels would not escape single quotes (GH 60190)

  • Bug in reindexing of DataFrame with PeriodDtype columns in case of consolidated block (GH 60980, GH 60273)

  • Bug in DataFrame.__getitem__() returning modified columns when called with slice in Python 3.12 (GH 57500)

  • Bug in DataFrame.loc.__getitem__() and DataFrame.iloc.__getitem__() with a CategoricalDtype column with integer categories raising when trying to index a row containing a NaN entry (GH 58954)

  • Bug in Index.__getitem__() incorrectly raising with a 0-dim np.ndarray key (GH 55601)

  • Bug in Index.get_indexer() not casting missing values correctly for new string datatype (GH 55833)

  • Bug in Index.intersection(), Index.union(), MultiIndex.intersection(), and MultiIndex.union() returning a reference to the original Index instead of a new instance when operating on identical indexes, which could cause metadata corruption when modifying the result (GH 63169)

  • Bug in adding new rows with DataFrame.loc.__setitem__() or Series.loc.__setitem__ which failed to retain dtype on the object’s index in some cases (GH 41626)

  • Bug in indexing on a DatetimeIndex with a timestamp[pyarrow] dtype or on a TimedeltaIndex with a duration[pyarrow] dtype (GH 62277)

Missing#

MultiIndex#

I/O#

Period#

Plotting#

Groupby/resample/rolling#

Reshaping#

Sparse#

ExtensionArray#

  • Bug in arrays.ArrowExtensionArray.__setitem__() which caused wrong behavior when using an integer array with repeated values as a key (GH 58530)

  • Bug in ArrowExtensionArray.factorize() where NA values were dropped when input was dictionary-encoded even when dropna was set to False(GH 60567)

  • Bug in NDArrayBackedExtensionArray.take() which produced arrays whose dtypes didn’t match their underlying data, when called with integer arrays (GH 62448)

  • Bug in api.types.is_datetime64_any_dtype() where a custom ExtensionDtype would return False for array-likes (GH 57055)

  • Bug in Arrow-backed duration and timestamp reductions (e.g. sum, min, max, median, mean) incorrectly returning stdlib datetime objects instead of Timedelta and Timestamp for resolutions other than nanoseconds (GH 63170)

  • Bug in comparison between object with ArrowDtype and incompatible-dtyped (e.g. string vs bool) incorrectly raising instead of returning all-False (for ==) or all-True (for !=) (GH 59505)

  • Bug in constructing pandas data structures when passing into dtype a string of the type followed by [pyarrow] while PyArrow is not installed would raise NameError rather than ImportError (GH 57928)

  • Bug in various DataFrame reductions for pyarrow temporal dtypes returning incorrect dtype when result was null (GH 59234)

  • Fixed flex arithmetic with ExtensionArray operands raising when fill_value was passed. (GH 62467)

Styler#

  • Bug in Styler.to_latex() where styling column headers when combined with a hidden index or hidden index-levels is fixed.

Other#

Contributors#

A total of 729 people contributed patches to this release. People with a “+” by their names contributed a patch for the first time.

  • 121238257 +

  • 3w36zj6 +

  • ADITYA KUSHWAHA +

  • ADITYA V J +

  • Abby VeCasey +

  • Abdulaziz Aloqeely

  • Abel Sanchez +

  • Abel Tavares +

  • Abhijit Chakraborty +

  • Abhinav +

  • Abhinav Reddy +

  • Abhinav Thimma +

  • Abhishek Chaudhari +

  • Abkari Mohammed Sayeem +

  • Aditya Ghosh +

  • Aditya Jha +

  • Aditya060 +

  • Agriya Khetarpal +

  • Ahmed Khairy +

  • Aidan Feldman

  • Aidos Kanapyanov

  • Akashisang +

  • Akshay Jain +

  • Albert Villanova del Moral

  • Alex

  • Alex Malins

  • Alexey Murz Korepov +

  • Alfredo Carella +

  • Alp +

  • Aman Sharma +

  • Amey Shinde +

  • Amin Allahyar +

  • Amir +

  • Amy Fung +

  • AnaDenisa +

  • Anand Mukherjee +

  • Andre Correia +

  • AndreyKolomiets +

  • André +

  • Andy

  • Angela Liss +

  • Aniket

  • Animcogn +

  • Anish Karki +

  • Anish Karthik +

  • Ankit Dhokariya +

  • Annika +

  • Anthony Speicher +

  • Antonio Valentino +

  • Antriksh006 +

  • Anurag Varma +

  • Aokizy2 +

  • Apoorv +

  • Arthur Laureus Wigo +

  • Arthur Wigo +

  • Artur Kenzo Obara Kawazoe +

  • Aryn1102 +

  • Ashar Khan +

  • Asish Mahapatra

  • Augustus +

  • Austin +

  • Austin Rhodes +

  • AustinOregonState +

  • Axeldnahcram +

  • Benjamin M +

  • Biplav Barua +

  • Borja Elizalde +

  • Brandon Norton +

  • Brandon Xu +

  • BreezeLune +

  • Brett Dixon +

  • Brian Christian +

  • Brian M +

  • Caden Gobat +

  • CaesarTY +

  • Carlo Barth +

  • Carson Fox +

  • Chaarvi Bansal +

  • ChiLin Chiu

  • Chris

  • Chris Hewitt +

  • Chris Xiang +

  • Christian Bläul +

  • Christian Castro +

  • Christine P. Chai +

  • Christopher Horn, PhD +

  • Christopher Titchen +

  • Christopher Xiang +

  • Claude Opus 4.5 +

  • Cliff Kerr +

  • Clément Robert

  • Code_Blooded +

  • Connor Wallace +

  • Cornelius Roemer +

  • Cristiano Sampaio +

  • Cristina Yenyxe Gonzalez Garcia +

  • DL Lim +

  • Dan Lawson +

  • Danferno +

  • Daniel Pinto Salazar +

  • Daniel S +

  • Dave Bunten +

  • Dave Tapley +

  • David Carvalho +

  • David Krych

  • Davit Gyulnazaryan +

  • DaxServer +

  • Dea María Léon

  • Deekshita +

  • Deen-dot +

  • Deepak Kapila +

  • Deepak Saldanha +

  • Denis Karadaş +

  • Denis Matsiusheuski +

  • Derek M. Knowlton +

  • Dhruv B Shetty

  • Dinesh Dawonauth +

  • Dipanshi Bansal +

  • Divya Sharma +

  • Dmitry Korotaev +

  • Dominik Smrž +

  • Echedey Luis +

  • Eduard Akhmetshin +

  • Edward FANG +

  • Ehsan Totoni +

  • Elliott Sales de Andrade

  • EngSongYeong +

  • Enrico Massa +

  • Eric Brown +

  • Eric Chen +

  • Eric Larson +

  • Espoir Murhabazi +

  • Ethan V Van Hao +

  • Eve Loraine Nuñal +

  • Evgenii Mosikhin

  • Ewout ter Hoeven

  • FLOURA ANGEL +

  • Fandi Meng +

  • Fangchen Li

  • Farsidetfs +

  • Fawaz Ahmed +

  • Fidorc80 +

  • Flavia Y. Ouyang +

  • Florian Bourgey +

  • Florian Jetter

  • Francesco Bruzzesi +

  • Francisco Kurucz +

  • Frank +

  • French_Ball +

  • FuzzyParrabellum +

  • G Karthik Koundinya +

  • Gael Varoquaux +

  • GauravM +

  • Geeeeeene +

  • Gen Sato +

  • George He +

  • Georgina Scott +

  • Georgios Giannakoulias +

  • Georgios Malandrakis +

  • Gianluca Ficarelli

  • Gleb Khmyznikov +

  • Goutham Anand +

  • Gowtham Kumar K. +

  • Grant Garrett-Grossman +

  • Gregers Thomas Skat Rørdam +

  • Guilherme Martins Crocetti +

  • GuruprashanthKrishnakumar +

  • Hanxin Chen +

  • Hariharan P R +

  • Harini Krishnamurthy +

  • Harmen Stoppels +

  • Harsha Lakamsani +

  • Harshit Pande +

  • Hassan Rad +

  • Henry Cuzco +

  • HeoHeo +

  • Hongxu Jia +

  • Hridey Marwah +

  • Huanghz2001

  • Huilin Xu +

  • HuilinXu +

  • HulusiOzy +

  • Ian Thompson +

  • Iaroslav Igoshev +

  • Icaro Alves +

  • Ilya +

  • Ingo Stallknecht +

  • Irv Lustig

  • Isaac Virshup

  • Isuru Fernando

  • Ivruix +

  • JBurley +

  • JHM Darbyshire

  • JJLLWW +

  • Jack +

  • Jack Shewring +

  • JackCollins1991 +

  • JackCollins91

  • Jacob Eggerd +

  • Jacob Lazar +

  • Jake Thomas Trevallion

  • Jakob Zahn +

  • Jakub Błażejowski +

  • Jakub Raczyński +

  • Jakub Szkliniarz +

  • James Bourbeau

  • James Spencer

  • James Yuill +

  • Janez Demšar +

  • JaniceP +

  • Jason Mok +

  • Javier Marin Tur +

  • Jay

  • Jay Ahn +

  • Jayalakshmi M +

  • Jean K. +

  • Jeff Harrison +

  • Jennifer Benson +

  • Jeremy Tuloup

  • Jesse +

  • Jixun Sun +

  • John Hendricks +

  • John Paul Feliciano +

  • Jonas Bergner +

  • Jonathan Marriott +

  • Jonathan Reimer +

  • Jordan Murphy +

  • Joren Hammudoglu +

  • Joris Van den Bossche

  • Joseph Kleinhenz +

  • Josquin Larsen +

  • José Morales +

  • JuanCarlos3 +

  • Julian Harbeck +

  • Julian-Harbeck +

  • Julien Palard

  • JulienBacquart +

  • Justine Wezenaar +

  • Kamel Gazzaz +

  • Karen Javadyan +

  • Karl Tarbet +

  • Katsia +

  • Kei +

  • KeiOshima +

  • Kevin Amparado

  • Kevin Doshi +

  • Kevin Sheppard

  • Kevon Scott +

  • Khemkaran

  • Khemkaran Sevta

  • Khor Chean Wei

  • Kian Eliasi

  • Kiril Isakov +

  • Kirill +

  • Konstantin Malanchev +

  • Korotaev DV +

  • Kunal Jani +

  • Kushagr Arora +

  • LOCHAN PAUDEL

  • Lakshman +

  • Lakshya Upadhyaya +

  • Laurent Mutricy

  • Laurie O

  • Leo Gordon +

  • Lex Lei +

  • Li +

  • Lirong +

  • Lobna Allam +

  • Loic Diridollou

  • Lonercode +

  • Louis Maddox +

  • Loïc Estève

  • Lu Yibo +

  • Luke Manley

  • Lysandros Nikolaou

  • Maaz Bin Asif +

  • Maitrey Talware +

  • Mangesh Kashid +

  • Manish Ranjan Karna +

  • Manjunath L +

  • Manlai Amar +

  • Marc Garcia

  • Marc Jones +

  • Marc Mueller

  • Marco Aurélio A. Barbosa +

  • Marco Barbosa +

  • Marco Edward Gorelli

  • Marco Gorelli

  • MarcoGorelli

  • Maren Westermann

  • Maria Ivanova +

  • Mark Akritas +

  • Mark Bekooy +

  • Mark Ryan +

  • Martin Braquet +

  • Mateusz Sokół

  • Matt Braymer-Hayes

  • Matt Delengowski +

  • Matt Heeter +

  • Matt Page +

  • Matt Popovich +

  • Matteo Paltenghi +

  • Matthew Heguy +

  • Matthew Pak +

  • Matthew Roeschke

  • Matthew Simpson +

  • Matthieu Thiboust +

  • Maushumee +

  • Maximilian Nicholson +

  • Meet_Vasita +

  • Memoona Shah +

  • Michael

  • Michael Hu +

  • Michael Moyles +

  • Michael Vincent Mannino +

  • Michaël Defferrard +

  • Michał Górny

  • Michelino Gali +

  • Michiel De Muynck +

  • Mien (Josephine) Nguyen +

  • Miguel Cárdenas +

  • Mika Allert +

  • Mike Perrone +

  • Mohammad Ahmadi

  • Moshe Kaplan +

  • Movsisyan +

  • Myles Scolnick +

  • Naresh Kumar +

  • Natalia Mokeeva

  • Natalie Dettmer +

  • Nathan Goldbaum

  • Navya Srivastava +

  • NewUserHa +

  • Nick Crews

  • Nikhil +

  • Niklas Rousset +

  • Niruta Talwekar +

  • Nithurshen +

  • Nitish Satyavolu +

  • Noa Tamir

  • Noah Asing +

  • Nrezhang +

  • Olivier H. +

  • PRANAV +

  • Parthava Adabala +

  • Parthi

  • Pascal Brochart +

  • Pascal Corpet +

  • Patrick Hoefler

  • Paul

  • Paul Behrisch +

  • Paul Bissex +

  • Paulo S. Costa

  • Pedro Diogo +

  • Pedro Freitas +

  • Pedro Marques +

  • Pedro Santos +

  • PenguinPen +

  • Peter Nguyen +

  • Peter Westling +

  • Petroncini +

  • Philipp Hoffmann +

  • Pol Rius +

  • Praateek Mahajan +

  • Pranav Raghu +

  • Pranav Wadhwa +

  • Prathamesh +

  • Preetham Yerragudi +

  • Qaiser Abbasi +

  • Quang Nguyễn

  • Quentin Lhoest +

  • Rafael Fontenelle +

  • Raffi Enficiaud +

  • Rajvi Gemawat +

  • Ralf Gommers

  • Randolf Scholz

  • Richard Howe +

  • Richard Shadrach

  • Ritoban Dutta +

  • Ritwiz Sinha +

  • Rob

  • Robert Schmidtke

  • Robert Utterback +

  • Robert Wolff +

  • Robin

  • Robin Mader +

  • Robin Shindelman +

  • Rohan Jain

  • Roline Stapny Saldanha +

  • Ron Arbo +

  • Rui Amaral +

  • Ruifeng Zheng +

  • Rustam Ali +

  • Rutrum +

  • S +

  • SAHARSH TIBREWALA +

  • SALCAN

  • Saadha Salim +

  • Sam Baumann +

  • Samuel +

  • Samuel Chai

  • Samuel Oranyeli

  • Samuel Xavier +

  • Sanchit Rishi +

  • SanchitD +

  • Sangam Paudel +

  • Sanjana Moudgalya +

  • Santhosh Kumar Bethi +

  • Saraswathy Kalaiselvan +

  • Sathvik Mulukutla +

  • Scott Talbert

  • Sebastian Berg

  • Sebastian Correa +

  • SebastianOuslis +

  • Sergey B Kirpichev +

  • Sergio Livi +

  • Shabab Karim

  • Shashwat Agrawal

  • ShaunSrirangam +

  • Shawn Liu +

  • Shi Entong +

  • Shing Chan +

  • Shmulik Cohen +

  • Shreyal Gupta +

  • Shreyas +

  • Shubham Sarkar +

  • Shubhang Sinha +

  • Shubhank Gyawali +

  • Shubhankar Agrawal +

  • Siddhesh Bangar +

  • SiemBerhane +

  • Simon Hawkins

  • Sinclair Hudson +

  • Sivasweatha Umamaheswaran +

  • Sofia Soares +

  • Sparsh Sah +

  • Sreeja Govardhana +

  • Srinitya Kondapally +

  • Stefano Silvestri +

  • Steffen Rehberg

  • Stepfen Shawn

  • Steven Schaerer

  • SubsequentlySneeds +

  • Suhrid Singh +

  • Sukriti +

  • Sumeet Bhatnagar +

  • Swati Sneha +

  • T. Koskamp +

  • TJ +

  • Tal yahav +

  • Tanya Bouman +

  • TechnoShip123 +

  • Tejas Rajput +

  • Tejaswini V +

  • TessAfanasyeva +

  • Thad Guidry +

  • Thai Villaluna +

  • Thanh Lam DANG +

  • Thanh Le-Cong +

  • Thi PHAN +

  • Thierry Moisan

  • Thomas A Caswell

  • Thomas Baumann

  • Thomas Dixon +

  • Thomas H

  • Thomas Heavey

  • Thomas Holder +

  • Thomas Li

  • Thomaz +

  • Thomaz Miranda +

  • Thummalapalli Sai Teja Sri Sanjana +

  • Tiffany Xiao +

  • Tilova Shahrin +

  • Tim Hoffmann

  • Tim Smith +

  • Tim Sweña (Swast) +

  • Tim Yang

  • Tirthraj Parmar +

  • Tolker-KU

  • Tom Augspurger

  • Tomaz Silva +

  • Tonow +

  • Torsten Wörtwein

  • Trevor Serrao +

  • Trinh Quoc Anh

  • Tristan Koskamp +

  • Tuhin Sharma +

  • Tunahan Yardımcı +

  • Tyson Cung +

  • U-S-jun +

  • UDIT BALIYAN +

  • UV +

  • Udit Baliyan +

  • Ulrich Dobramysl +

  • VISWESWARAN1998 +

  • Valentin Iovene

  • Veit Heller +

  • Venkat +

  • Venkata Akhil Mettu +

  • Vibavari Gurunathan +

  • Vignesh Iyer +

  • Vijay Sarathy +

  • Vikram Kumar +

  • Vineet Kumar +

  • Vishal Shivam +

  • Viswa Sai Ammiraju Bonam +

  • Vladimir Fokow

  • Vrashank Shetty +

  • W. H. Wang +

  • Wang Haoxiang +

  • Wei-Hsiang (Matt) Wang +

  • Wes Turner

  • WhimsyHippo +

  • Will Sorenson +

  • William Andrea

  • William Ayd

  • William Joshua King +

  • William King +

  • Winnie +

  • Wong2333 +

  • Work +

  • XY +

  • Xiao Yuan

  • Y.X +

  • Yana Mishula +

  • Yashpal Ahlawat +

  • Yassin Abdelghany +

  • Yaswanth Kumar +

  • Yi-Fan Wang +

  • Yi-Han Chen +

  • Yinon Horev +

  • YinonHorev +

  • Yoshimu U. Nats +

  • Yuki Kitayama

  • Yuki Kobayashi +

  • Yuri Batista Ishizawa +

  • Yuvraj Pradhan +

  • ZA1815 +

  • ZKaoChi +

  • Zachary Collins +

  • Zanir Pirani +

  • ZanirP +

  • Zephy +

  • Zhengbo Wang

  • Zorex Salvo +

  • Zrahay +

  • [Annika Rudolph] +

  • aBiR1D +

  • aaron-robeson-8451

  • aaronchucarroll +

  • abonte

  • ahmedbektic +

  • aimlnerd +

  • amansharma612 +

  • ammar-qazi +

  • ananiavito +

  • anishkarki +

  • anzber +

  • aokizy +

  • aram-cinnamon

  • asoledad33 +

  • auderson

  • avecasey +

  • averagejoy +

  • avm19 +

  • aydinkhan2005 +

  • bdwzhangumich +

  • benjamindonnachie +

  • bluestarunderscore +

  • callumfrederiksen +

  • calvin +

  • chaoyihu +

  • chen +

  • chi +

  • cloudboat +

  • cmjcharlton +

  • cmp0xff +

  • cristian_scobioala +

  • dajale423 +

  • datapythonista +

  • davidesquer +

  • dependabot[bot]

  • devin-ai-integration[bot] +

  • dkane01 +

  • droussea2001 +

  • dshettyepi +

  • dsousa +

  • easternsun7 +

  • eicchen +

  • eicchen02 +

  • eightyseven +

  • eilonc-cx +

  • ellaella12 +

  • ensalada-de-pechuga +

  • er-eis +

  • erichxchen +

  • eshaready +

  • fatslow +

  • gabuzi +

  • gameofby +

  • gboeker +

  • hafeja +

  • haffara +

  • harinik +

  • huhu +

  • huisman +

  • hye ryung cho +

  • iangainey +

  • ianlv +

  • igeni +

  • imTejasRajput +

  • invain01 +

  • invalidarg +

  • ivanpan0626 +

  • ivonastojanovic +

  • jad +

  • james-magee +

  • jarent-nvidia +

  • jayendhargautham +

  • jbrockmendel

  • jeffersbaxter +

  • jeffery nosakhare Omorodion +

  • jeffreykenneth +

  • jerrywbirnbaum +

  • jgao8 +

  • jl_win_a +

  • jmalp +

  • jmarin +

  • johnff9 +

  • johnpaulfeliciano98 +

  • johnyu013 +

  • jrmylow +

  • justmhie +

  • jzwick +

  • karnbirrandhawa +

  • koushik-rout-samsung +

  • kpvenkat47 +

  • krishna datta +

  • ktseng4096 +

  • lamprinikourou +

  • lfffkh +

  • lif +

  • llayague +

  • mateomramos +

  • matiaslindgren +

  • matsidzi +

  • mattbest +

  • mazhar996 +

  • messense +

  • microslaw +

  • mikkas456 +

  • morotti

  • mroeschke * DOC: fix example for iv_idx.left * Implement test for GH #21340 * minor fixup * Lint contribution * Make spacing consistent * Lint * Remove duplicate column construction * Avoid DeprecationWarning by setting include_groups=False in apply ——— Co-authored-by: Jason Mok +

  • mroeschke +

  • musvaage +

  • mutricyl +

  • myenugula +

  • ncknelson +

  • ofsouzap +

  • omahs +

  • ooo oo +

  • pandas Development Team

  • partev

  • paul +

  • pedrocariellof +

  • pre-commit-ci[bot]

  • ptth222

  • r0rshark +

  • rdzantoine.pro@gmail.com +

  • renanffernando +

  • rhshadrach

  • richard +

  • ritwika314 +

  • rmorotti +

  • rohanjain101

  • root +

  • s1099 +

  • sah0725 +

  • santhoshbethi +

  • sdhjebngc +

  • sharkipelago +

  • shriyakalakata +

  • sjalkote +

  • skalwaghe_56 +

  • sliuos +

  • sooooooing +

  • specialkapa +

  • sshu2017 +

  • steeleelliott03 +

  • stevenae +

  • sunlight +

  • surenpoghosian +

  • suzyahyah +

  • taranarmo +

  • tasfia8

  • tharun-mk +

  • thetestspecimen +

  • thomasdamcevski +

  • thwait +

  • tisjayy +

  • tomas-cc +

  • u7397058 +

  • undermyumbrella1 +

  • v-lozko +

  • veljanin +

  • viable-alternative +

  • wanglc02 +

  • wdyy20041223 +

  • wenchen-cai +

  • william larkin +

  • wooseogchoi +

  • wysiwyg +

  • xiaohuanlin +

  • xingyubobo33333 +

  • xxx.Yan +

  • yashb

  • yjennyli +

  • yokomotod +

  • zachyattack23 +

  • zhan7236 +

  • zhiqiangxu +

  • zishan044 +

  • zjweiss-google +

  • zslsally +

  • Álvaro Kothe

  • Óscar Gómez +

  • 张博闻 +

  • 许知恒 +

  • 🍌Shawn +