2.0.0 版本新特性 (2023 年 4 月 3 日)#

以下是 pandas 2.0.0 中的更改。有关包括其他 pandas 版本在内的完整更改日志,请参阅 发行说明

增强功能#

使用 pip extras 安装可选依赖项#

使用 pip 安装 pandas 时,还可以通过指定 extras 来安装一系列可选依赖项。

pip install "pandas[performance, aws]>=2.0.0"

可用的 extras 在安装指南中可以找到,包括 [all, performance, computation, fss, aws, gcp, excel, parquet, feather, hdf5, spss, postgresql, mysql, sql-other, html, xml, plot, output_formatting, clipboard, compression, test] (GH 39164)。

Index 现在可以容纳 NumPy 数值数据类型#

Index 现在可以使用任何 NumPy 数值数据类型 (GH 42717)。

此前,只能使用 int64uint64float64 数据类型

In [1]: pd.Index([1, 2, 3], dtype=np.int8)
Out[1]: Int64Index([1, 2, 3], dtype="int64")
In [2]: pd.Index([1, 2, 3], dtype=np.uint16)
Out[2]: UInt64Index([1, 2, 3], dtype="uint64")
In [3]: pd.Index([1, 2, 3], dtype=np.float32)
Out[3]: Float64Index([1.0, 2.0, 3.0], dtype="float64")

Int64IndexUInt64IndexFloat64Index 在 pandas 1.4 版本中已弃用,现已移除。现在应直接使用 Index,它现在可以接受所有 NumPy 数值数据类型,即 int8/int16/int32/int64/uint8/uint16/uint32/uint64/float32/float64 数据类型

In [1]: pd.Index([1, 2, 3], dtype=np.int8)
Out[1]: Index([1, 2, 3], dtype='int8')

In [2]: pd.Index([1, 2, 3], dtype=np.uint16)
Out[2]: Index([1, 2, 3], dtype='uint16')

In [3]: pd.Index([1, 2, 3], dtype=np.float32)
Out[3]: Index([1.0, 2.0, 3.0], dtype='float32')

Index 能够容纳 NumPy 数值数据类型意味着 Pandas 功能发生了一些变化。特别是,以前强制创建 64 位索引的操作,现在可以创建位大小更低的索引,例如 32 位索引。

下面是可能不完全的更改列表

  1. 现在使用 NumPy 数值数组实例化时会遵循 NumPy 数组的数据类型。以前,所有从 NumPy 数值数组创建的索引都被强制转换为 64 位。现在,例如,Index(np.array([1, 2, 3])) 在 32 位系统上将是 int32,而以前即使在 32 位系统上也会是 int64。使用数字列表实例化 Index 仍将返回 64 位数据类型,例如 Index([1, 2, 3]) 将具有 int64 数据类型,这与以前相同。

  2. DatetimeIndex 的各种数值日期时间属性(daymonthyear 等)以前是 int64 数据类型,而 arrays.DatetimeArray 则是 int32。现在它们在 DatetimeIndex 上也是 int32

    In [4]: idx = pd.date_range(start='1/1/2018', periods=3, freq='ME')
    
    In [5]: idx.array.year
    Out[5]: array([2018, 2018, 2018], dtype=int32)
    
    In [6]: idx.year
    Out[6]: Index([2018, 2018, 2018], dtype='int32')
    
  3. Series.sparse.from_coo() 创建的 Index 上的层级数据类型现在是 int32,与 scipy 稀疏矩阵上的 rows/cols 数据类型相同。以前它们是 int64 数据类型。

    In [7]: from scipy import sparse
    
    In [8]: A = sparse.coo_matrix(
       ...:     ([3.0, 1.0, 2.0], ([1, 0, 0], [0, 2, 3])), shape=(3, 4)
       ...: )
       ...: 
    
    In [9]: ser = pd.Series.sparse.from_coo(A)
    
    In [10]: ser.index.dtypes
    Out[10]: 
    level_0    int32
    level_1    int32
    dtype: object
    
  4. Index 无法使用 float16 数据类型实例化。以前,使用 float16 数据类型实例化 Index 会导致一个 Float64Index 具有 float64 数据类型。现在它会引发 NotImplementedError

    In [11]: pd.Index([1, 2, 3], dtype=np.float16)
    ---------------------------------------------------------------------------
    NotImplementedError                       Traceback (most recent call last)
    Cell In[11], line 1
    ----> 1 pd.Index([1, 2, 3], dtype=np.float16)
    
    File ~/work/pandas/pandas/pandas/core/indexes/base.py:577, in Index.__new__(cls, data, dtype, copy, name, tupleize_cols)
        573 arr = ensure_wrapped_if_datetimelike(arr)
        575 klass = cls._dtype_to_subclass(arr.dtype)
    --> 577 arr = klass._ensure_array(arr, arr.dtype, copy=False)
        578 result = klass._simple_new(arr, name, refs=refs)
        579 if dtype is None and is_pandas_object and data_dtype == np.object_:
    
    File ~/work/pandas/pandas/pandas/core/indexes/base.py:602, in Index._ensure_array(cls, data, dtype, copy)
        599     raise ValueError("Index data must be 1-dimensional")
        600 elif dtype == np.float16:
        601     # float16 not supported (no indexing engine)
    --> 602     raise NotImplementedError("float16 indexes are not supported")
        604 if copy:
        605     # asarray_tuplesafe does not always copy underlying data,
        606     #  so need to make sure that this happens
        607     data = data.copy()
    
    NotImplementedError: float16 indexes are not supported
    

参数 dtype_backend,用于返回 PyArrow 支持或 NumPy 支持的可空数据类型#

以下函数新增了关键字 dtype_backend (GH 36712)

当此选项设置为 "numpy_nullable" 时,它将返回一个由可空数据类型支持的 DataFrame

当此关键字设置为 "pyarrow" 时,这些函数将返回由 PyArrow 支持的可空 ArrowDtype DataFrame (GH 48957, GH 49997)

In [12]: import io

In [13]: data = io.StringIO("""a,b,c,d,e,f,g,h,i
   ....:     1,2.5,True,a,,,,,
   ....:     3,4.5,False,b,6,7.5,True,a,
   ....: """)
   ....: 

In [14]: df = pd.read_csv(data, dtype_backend="pyarrow")

In [15]: df.dtypes
Out[15]: 
a     int64[pyarrow]
b    double[pyarrow]
c      bool[pyarrow]
d    string[pyarrow]
e     int64[pyarrow]
f    double[pyarrow]
g      bool[pyarrow]
h    string[pyarrow]
i      null[pyarrow]
dtype: object

In [16]: data.seek(0)
Out[16]: 0

In [17]: df_pyarrow = pd.read_csv(data, dtype_backend="pyarrow", engine="pyarrow")

In [18]: df_pyarrow.dtypes
Out[18]: 
a     int64[pyarrow]
b    double[pyarrow]
c      bool[pyarrow]
d    string[pyarrow]
e     int64[pyarrow]
f    double[pyarrow]
g      bool[pyarrow]
h    string[pyarrow]
i      null[pyarrow]
dtype: object

写时复制改进#

  • 写时复制优化 中列出的方法中,新增了一种惰性复制机制,它将复制延迟到相关对象被修改时进行。当启用写时复制时,这些方法会返回视图,这与常规执行相比提供了显著的性能提升 (GH 49473)。

  • 当启用写时复制时,每次将 DataFrame 的单个列作为 Series 访问(例如 df["col"])时,现在总是返回一个新对象(而不是多次返回一个相同的、缓存的 Series 对象)。这确保了这些 Series 对象正确遵循写时复制规则 (GH 49450)

  • 当从现有 Series 构造 Series 时,默认 copy=FalseSeries 构造函数现在将创建一个惰性副本(将复制延迟到数据发生修改时进行)(GH 50471)

  • 当从现有 DataFrame 构造 DataFrame 时,默认 copy=FalseDataFrame 构造函数现在将创建一个惰性副本(将复制延迟到数据发生修改时进行)(GH 51239)

  • 当从 Series 对象的字典构造 DataFrame 并指定 copy=False 时,DataFrame 构造函数现在将对 DataFrame 的列使用这些 Series 对象的惰性副本 (GH 50777)

  • 当从 SeriesIndex 构造 DataFrame 并指定 copy=False 时,DataFrame 构造函数现在将遵循写时复制。

  • 当从 NumPy 数组构造时,DataFrameSeries 构造函数现在将默认复制数组,以避免在修改数组时改变 DataFrame / Series。指定 copy=False 以获取旧行为。当设置 copy=False 时,如果 NumPy 数组在 DataFrame / Series 创建后被修改,pandas 不保证正确的写时复制行为。

  • 当使用 DataFrame 调用时,DataFrame.from_records() 现在将遵循写时复制。

  • 尝试使用链式赋值设置值(例如 df["a"][1:3] = 0)在启用写时复制时现在总是会引发警告。在此模式下,链式赋值永远无法工作,因为我们总是设置到索引操作(getitem)结果的临时对象中,而该对象在写时复制下始终表现为副本。因此,通过链式赋值永远无法更新原始 Series 或 DataFrame。因此,会向用户引发一条信息性警告,以避免静默地不执行任何操作 (GH 49467)

  • inplace=True 时,DataFrame.replace() 现在将遵循写时复制机制。

  • DataFrame.transpose() 现在将遵循写时复制机制。

  • 可以原地执行的算术运算,例如 ser *= 2 现在将遵循写时复制机制。

  • DataFrame 具有 MultiIndex 列时,DataFrame.__getitem__() 现在将遵循写时复制机制。

  • Series 具有 MultiIndex 时,Series.__getitem__() 现在将遵循写时复制机制。

    Series 具有 MultiIndex

  • Series.view() 现在将遵循写时复制机制。

写时复制可以通过以下方式之一启用

pd.set_option("mode.copy_on_write", True)
pd.options.mode.copy_on_write = True

或者,写时复制可以在本地通过以下方式启用

with pd.option_context("mode.copy_on_write", True):
    ...

其他增强功能#

显著的错误修复#

这些错误修复可能会导致显著的行为变化。

DataFrameGroupBy.cumsum()DataFrameGroupBy.cumprod() 溢出而不是有损转换为浮点数#

在以前的版本中,应用 cumsumcumprod 时会转换为浮点数,即使结果可以用 int64 数据类型表示,也会导致不正确的结果。此外,当达到 int64 的限制时,聚合会像 NumPy 以及常规 DataFrame.cumprod()DataFrame.cumsum() 方法一样溢出 (GH 37493)。

旧行为

In [1]: df = pd.DataFrame({"key": ["b"] * 7, "value": 625})
In [2]: df.groupby("key")["value"].cumprod()[5]
Out[2]: 5.960464477539062e+16

我们返回了第 6 个值的不正确结果。

新行为

In [19]: df = pd.DataFrame({"key": ["b"] * 7, "value": 625})

In [20]: df.groupby("key")["value"].cumprod()
Out[20]: 
0                   625
1                390625
2             244140625
3          152587890625
4        95367431640625
5     59604644775390625
6    359414837200037393
Name: value, dtype: int64

我们在第 7 个值时溢出,但第 6 个值仍然正确。

DataFrameGroupBy.nth()SeriesGroupBy.nth() 现在表现为过滤操作#

在以前的 pandas 版本中,DataFrameGroupBy.nth()SeriesGroupBy.nth() 表现得好像它们是聚合操作一样。然而,对于大多数输入 n,它们可能会为每个组返回零行或多行。这意味着它们是过滤操作,类似于例如 DataFrameGroupBy.head()。pandas 现在将其视为过滤操作 (GH 13666)。

In [21]: df = pd.DataFrame({"a": [1, 1, 2, 1, 2], "b": [np.nan, 2.0, 3.0, 4.0, 5.0]})

In [22]: gb = df.groupby("a")

旧行为

In [5]: gb.nth(n=1)
Out[5]:
   A    B
1  1  2.0
4  2  5.0

新行为

In [23]: gb.nth(n=1)
Out[23]: 
   a    b
1  1  2.0
4  2  5.0

特别是,结果的索引是通过选择适当的行从输入中派生出来的。此外,当 n 大于组大小时,返回的是零行而不是 NaN

旧行为

In [5]: gb.nth(n=3, dropna="any")
Out[5]:
    B
A
1 NaN
2 NaN

新行为

In [24]: gb.nth(n=3, dropna="any")
Out[24]: 
Empty DataFrame
Columns: [a, b]
Index: []

向后不兼容的 API 更改#

使用不支持分辨率的 datetime64 或 timedelta64 数据类型构造#

在过去的版本中,当构造 SeriesDataFrame 并传入不支持分辨率(即除了“ns”之外的任何分辨率)的“datetime64”或“timedelta64”数据类型时,pandas 会静默地将给定的数据类型替换为其纳秒级对应物

旧行为:

In [5]: pd.Series(["2016-01-01"], dtype="datetime64[s]")
Out[5]:
0   2016-01-01
dtype: datetime64[ns]

In [6] pd.Series(["2016-01-01"], dtype="datetime64[D]")
Out[6]:
0   2016-01-01
dtype: datetime64[ns]

在 pandas 2.0 中,我们支持“s”、“ms”、“us”和“ns”分辨率。当传入支持的数据类型(例如“datetime64[s]”)时,结果现在具有完全请求的数据类型

新行为:

In [25]: pd.Series(["2016-01-01"], dtype="datetime64[s]")
Out[25]: 
0   2016-01-01
dtype: datetime64[s]

对于不支持的数据类型,pandas 现在会引发错误,而不是静默地替换为受支持的数据类型

新行为:

In [26]: pd.Series(["2016-01-01"], dtype="datetime64[D]")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[26], line 1
----> 1 pd.Series(["2016-01-01"], dtype="datetime64[D]")

File ~/work/pandas/pandas/pandas/core/series.py:584, in Series.__init__(self, data, index, dtype, name, copy, fastpath)
    582         data = data.copy()
    583 else:
--> 584     data = sanitize_array(data, index, dtype, copy)
    586     manager = _get_option("mode.data_manager", silent=True)
    587     if manager == "block":

File ~/work/pandas/pandas/pandas/core/construction.py:648, in sanitize_array(data, index, dtype, copy, allow_2d)
    645     subarr = np.array([], dtype=np.float64)
    647 elif dtype is not None:
--> 648     subarr = _try_cast(data, dtype, copy)
    650 else:
    651     subarr = maybe_convert_platform(data)

File ~/work/pandas/pandas/pandas/core/construction.py:808, in _try_cast(arr, dtype, copy)
    803     return lib.ensure_string_array(arr, convert_na_value=False, copy=copy).reshape(
    804         shape
    805     )
    807 elif dtype.kind in "mM":
--> 808     return maybe_cast_to_datetime(arr, dtype)
    810 # GH#15832: Check if we are requesting a numeric dtype and
    811 # that we can convert the data to the requested dtype.
    812 elif dtype.kind in "iu":
    813     # this will raise if we have e.g. floats

File ~/work/pandas/pandas/pandas/core/dtypes/cast.py:1228, in maybe_cast_to_datetime(value, dtype)
   1224     raise TypeError("value must be listlike")
   1226 # TODO: _from_sequence would raise ValueError in cases where
   1227 #  _ensure_nanosecond_dtype raises TypeError
-> 1228 _ensure_nanosecond_dtype(dtype)
   1230 if lib.is_np_dtype(dtype, "m"):
   1231     res = TimedeltaArray._from_sequence(value, dtype=dtype)

File ~/work/pandas/pandas/pandas/core/dtypes/cast.py:1285, in _ensure_nanosecond_dtype(dtype)
   1282     raise ValueError(msg)
   1283 # TODO: ValueError or TypeError? existing test
   1284 #  test_constructor_generic_timestamp_bad_frequency expects TypeError
-> 1285 raise TypeError(
   1286     f"dtype={dtype} is not supported. Supported resolutions are 's', "
   1287     "'ms', 'us', and 'ns'"
   1288 )

TypeError: dtype=datetime64[D] is not supported. Supported resolutions are 's', 'ms', 'us', and 'ns'

值计数将结果名称设置为 count#

在过去的版本中,当运行 Series.value_counts() 时,结果会继承原始对象的名称,而结果索引则没有名称。这会导致在重置索引时产生混淆,并且列名将与列值不对应。现在,结果名称将是 'count'(如果传入 normalize=True 则为 'proportion'),并且索引将以原始对象命名 (GH 49497)。

旧行为:

In [8]: pd.Series(['quetzal', 'quetzal', 'elk'], name='animal').value_counts()

Out[2]:
quetzal    2
elk        1
Name: animal, dtype: int64

新行为:

In [27]: pd.Series(['quetzal', 'quetzal', 'elk'], name='animal').value_counts()
Out[27]: 
animal
quetzal    2
elk        1
Name: count, dtype: int64

其他 value_counts 方法(例如 DataFrame.value_counts())也类似。

禁止 astype 转换为不支持的 datetime64/timedelta64 数据类型#

在以前的版本中,将 SeriesDataFramedatetime64[ns] 转换为不同的 datetime64[X] 数据类型时,会返回 datetime64[ns] 数据类型,而不是请求的数据类型。在 pandas 2.0 中,增加了对“datetime64[s]”、“datetime64[ms]”和“datetime64[us]”数据类型的支持,因此转换为这些数据类型时会精确地得到请求的数据类型

旧行为:

In [28]: idx = pd.date_range("2016-01-01", periods=3)

In [29]: ser = pd.Series(idx)

旧行为:

In [4]: ser.astype("datetime64[s]")
Out[4]:
0   2016-01-01
1   2016-01-02
2   2016-01-03
dtype: datetime64[ns]

使用新行为,我们得到了精确请求的数据类型

新行为:

In [30]: ser.astype("datetime64[s]")
Out[30]: 
0   2016-01-01
1   2016-01-02
2   2016-01-03
dtype: datetime64[s]

对于不支持的分辨率,例如“datetime64[D]”,我们会引发错误,而不是静默地忽略请求的数据类型

新行为:

In [31]: ser.astype("datetime64[D]")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[31], line 1
----> 1 ser.astype("datetime64[D]")

File ~/work/pandas/pandas/pandas/core/generic.py:6662, in NDFrame.astype(self, dtype, copy, errors)
   6656     results = [
   6657         ser.astype(dtype, copy=copy, errors=errors) for _, ser in self.items()
   6658     ]
   6660 else:
   6661     # else, only a single dtype is given
-> 6662     new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors)
   6663     res = self._constructor_from_mgr(new_data, axes=new_data.axes)
   6664     return res.__finalize__(self, method="astype")

File ~/work/pandas/pandas/pandas/core/internals/managers.py:430, in BaseBlockManager.astype(self, dtype, copy, errors)
    427 elif using_copy_on_write():
    428     copy = False
--> 430 return self.apply(
    431     "astype",
    432     dtype=dtype,
    433     copy=copy,
    434     errors=errors,
    435     using_cow=using_copy_on_write(),
    436 )

File ~/work/pandas/pandas/pandas/core/internals/managers.py:363, in BaseBlockManager.apply(self, f, align_keys, **kwargs)
    361         applied = b.apply(f, **kwargs)
    362     else:
--> 363         applied = getattr(b, f)(**kwargs)
    364     result_blocks = extend_blocks(applied, result_blocks)
    366 out = type(self).from_blocks(result_blocks, self.axes)

File ~/work/pandas/pandas/pandas/core/internals/blocks.py:784, in Block.astype(self, dtype, copy, errors, using_cow, squeeze)
    781         raise ValueError("Can not squeeze with more than one column.")
    782     values = values[0, :]  # type: ignore[call-overload]
--> 784 new_values = astype_array_safe(values, dtype, copy=copy, errors=errors)
    786 new_values = maybe_coerce_values(new_values)
    788 refs = None

File ~/work/pandas/pandas/pandas/core/dtypes/astype.py:237, in astype_array_safe(values, dtype, copy, errors)
    234     dtype = dtype.numpy_dtype
    236 try:
--> 237     new_values = astype_array(values, dtype, copy=copy)
    238 except (ValueError, TypeError):
    239     # e.g. _astype_nansafe can fail on object-dtype of strings
    240     #  trying to convert to float
    241     if errors == "ignore":

File ~/work/pandas/pandas/pandas/core/dtypes/astype.py:179, in astype_array(values, dtype, copy)
    175     return values
    177 if not isinstance(values, np.ndarray):
    178     # i.e. ExtensionArray
--> 179     values = values.astype(dtype, copy=copy)
    181 else:
    182     values = _astype_nansafe(values, dtype, copy=copy)

File ~/work/pandas/pandas/pandas/core/arrays/datetimes.py:741, in DatetimeArray.astype(self, dtype, copy)
    739 elif isinstance(dtype, PeriodDtype):
    740     return self.to_period(freq=dtype.freq)
--> 741 return dtl.DatetimeLikeArrayMixin.astype(self, dtype, copy)

File ~/work/pandas/pandas/pandas/core/arrays/datetimelike.py:517, in DatetimeLikeArrayMixin.astype(self, dtype, copy)
    513 elif (dtype.kind in "mM" and self.dtype != dtype) or dtype.kind == "f":
    514     # disallow conversion between datetime/timedelta,
    515     # and conversions for any datetimelike to float
    516     msg = f"Cannot cast {type(self).__name__} to dtype {dtype}"
--> 517     raise TypeError(msg)
    518 else:
    519     return np.asarray(self, dtype=dtype)

TypeError: Cannot cast DatetimeArray to dtype datetime64[D]

对于从 timedelta64[ns] 数据类型进行的转换,旧行为会转换为浮点格式。

旧行为:

In [32]: idx = pd.timedelta_range("1 Day", periods=3)

In [33]: ser = pd.Series(idx)

旧行为:

In [7]: ser.astype("timedelta64[s]")
Out[7]:
0     86400.0
1    172800.0
2    259200.0
dtype: float64

In [8]: ser.astype("timedelta64[D]")
Out[8]:
0    1.0
1    2.0
2    3.0
dtype: float64

新行为,与 datetime64 类似,要么精确返回请求的数据类型,要么引发错误

新行为:

In [34]: ser.astype("timedelta64[s]")
Out[34]: 
0   1 days
1   2 days
2   3 days
dtype: timedelta64[s]

In [35]: ser.astype("timedelta64[D]")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[35], line 1
----> 1 ser.astype("timedelta64[D]")

File ~/work/pandas/pandas/pandas/core/generic.py:6662, in NDFrame.astype(self, dtype, copy, errors)
   6656     results = [
   6657         ser.astype(dtype, copy=copy, errors=errors) for _, ser in self.items()
   6658     ]
   6660 else:
   6661     # else, only a single dtype is given
-> 6662     new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors)
   6663     res = self._constructor_from_mgr(new_data, axes=new_data.axes)
   6664     return res.__finalize__(self, method="astype")

File ~/work/pandas/pandas/pandas/core/internals/managers.py:430, in BaseBlockManager.astype(self, dtype, copy, errors)
    427 elif using_copy_on_write():
    428     copy = False
--> 430 return self.apply(
    431     "astype",
    432     dtype=dtype,
    433     copy=copy,
    434     errors=errors,
    435     using_cow=using_copy_on_write(),
    436 )

File ~/work/pandas/pandas/pandas/core/internals/managers.py:363, in BaseBlockManager.apply(self, f, align_keys, **kwargs)
    361         applied = b.apply(f, **kwargs)
    362     else:
--> 363         applied = getattr(b, f)(**kwargs)
    364     result_blocks = extend_blocks(applied, result_blocks)
    366 out = type(self).from_blocks(result_blocks, self.axes)

File ~/work/pandas/pandas/pandas/core/internals/blocks.py:784, in Block.astype(self, dtype, copy, errors, using_cow, squeeze)
    781         raise ValueError("Can not squeeze with more than one column.")
    782     values = values[0, :]  # type: ignore[call-overload]
--> 784 new_values = astype_array_safe(values, dtype, copy=copy, errors=errors)
    786 new_values = maybe_coerce_values(new_values)
    788 refs = None

File ~/work/pandas/pandas/pandas/core/dtypes/astype.py:237, in astype_array_safe(values, dtype, copy, errors)
    234     dtype = dtype.numpy_dtype
    236 try:
--> 237     new_values = astype_array(values, dtype, copy=copy)
    238 except (ValueError, TypeError):
    239     # e.g. _astype_nansafe can fail on object-dtype of strings
    240     #  trying to convert to float
    241     if errors == "ignore":

File ~/work/pandas/pandas/pandas/core/dtypes/astype.py:179, in astype_array(values, dtype, copy)
    175     return values
    177 if not isinstance(values, np.ndarray):
    178     # i.e. ExtensionArray
--> 179     values = values.astype(dtype, copy=copy)
    181 else:
    182     values = _astype_nansafe(values, dtype, copy=copy)

File ~/work/pandas/pandas/pandas/core/arrays/timedeltas.py:358, in TimedeltaArray.astype(self, dtype, copy)
    354         return type(self)._simple_new(
    355             res_values, dtype=res_values.dtype, freq=self.freq
    356         )
    357     else:
--> 358         raise ValueError(
    359             f"Cannot convert from {self.dtype} to {dtype}. "
    360             "Supported resolutions are 's', 'ms', 'us', 'ns'"
    361         )
    363 return dtl.DatetimeLikeArrayMixin.astype(self, dtype, copy=copy)

ValueError: Cannot convert from timedelta64[ns] to timedelta64[D]. Supported resolutions are 's', 'ms', 'us', 'ns'

UTC 和固定偏移时区默认使用标准库 tzinfo 对象#

在以前的版本中,用于表示 UTC 的默认 tzinfo 对象是 pytz.UTC。在 pandas 2.0 中,我们转而默认使用 datetime.timezone.utc。类似地,对于表示固定 UTC 偏移的时区,我们使用 datetime.timezone 对象而不是 pytz.FixedOffset 对象。请参阅 (GH 34916)

旧行为:

In [2]: ts = pd.Timestamp("2016-01-01", tz="UTC")
In [3]: type(ts.tzinfo)
Out[3]: pytz.UTC

In [4]: ts2 = pd.Timestamp("2016-01-01 04:05:06-07:00")
In [3]: type(ts2.tzinfo)
Out[5]: pytz._FixedOffset

新行为:

In [36]: ts = pd.Timestamp("2016-01-01", tz="UTC")

In [37]: type(ts.tzinfo)
Out[37]: datetime.timezone

In [38]: ts2 = pd.Timestamp("2016-01-01 04:05:06-07:00")

In [39]: type(ts2.tzinfo)
Out[39]: datetime.timezone

对于既非 UTC 也非固定偏移的时区,例如“US/Pacific”,我们继续默认使用 pytz 对象。

空的 DataFrame/Series 现在将默认拥有 RangeIndex#

此前,在不指定轴(index=Nonecolumns=None)的情况下构造一个空的(dataNone 或空的类列表参数)SeriesDataFrame,会返回一个 object 数据类型的空 Index

现在,轴返回一个空的 RangeIndex (GH 49572)。

旧行为:

In [8]: pd.Series().index
Out[8]:
Index([], dtype='object')

In [9] pd.DataFrame().axes
Out[9]:
[Index([], dtype='object'), Index([], dtype='object')]

新行为:

In [40]: pd.Series().index
Out[40]: RangeIndex(start=0, stop=0, step=1)

In [41]: pd.DataFrame().axes
Out[41]: [RangeIndex(start=0, stop=0, step=1), RangeIndex(start=0, stop=0, step=1)]

DataFrame 到 LaTeX 有一个新的渲染引擎#

现有的 DataFrame.to_latex() 已重构,以利用此前在 Styler.to_latex() 下可用的扩展实现。参数签名类似,尽管 col_space 已被移除,因为它被 LaTeX 引擎忽略。此渲染引擎还需要 jinja2 作为依赖项,需要安装,因为渲染是基于 jinja2 模板的。

以下 pandas LaTeX 选项不再使用并已移除。通用的最大行和列参数仍然保留,但对于此功能应替换为 Styler 的等效项。提供类似功能的替代选项如下所示

  • display.latex.escape:已替换为 styler.format.escape

  • display.latex.longtable:已替换为 styler.latex.environment

  • display.latex.multicolumndisplay.latex.multicolumn_formatdisplay.latex.multirow:已替换为 styler.sparse.rowsstyler.sparse.columnsstyler.latex.multirow_alignstyler.latex.multicol_align

  • display.latex.repr:已替换为 styler.render.repr

  • display.max_rowsdisplay.max_columns:替换为 styler.render.max_rowsstyler.render.max_columnsstyler.render.max_elements

请注意,由于此更改,一些默认值也已更改

  • multirow 现在默认为 True

  • multirow_align 默认值为 “r” 而不是 “l”

  • multicol_align 默认值为 “r” 而不是 “l”

  • escape 现在默认为 False

请注意,_repr_latex_ 的行为也已更改。以前设置 display.latex.repr 只在使用 nbconvert 导出 Jupyter Notebook 时生成 LaTeX,而不是用户运行 Notebook 时。现在 styler.render.repr 选项允许控制 Jupyter Notebook 中特定操作的输出(不仅仅是 nbconvert)。请参阅 GH 39911

依赖项的最低版本提高#

一些依赖项的最低支持版本已更新。如果已安装,我们现在要求

最低版本

必需

已更改

mypy (开发)

1.0

X

pytest (开发)

7.0.0

X

pytest-xdist (开发)

2.2.0

X

hypothesis (开发)

6.34.2

X

python-dateutil

2.8.2

X

X

tzdata

2022.1

X

X

对于可选库,一般建议使用最新版本。下表列出了在 pandas 开发过程中当前正在测试的每个库的最低版本。低于最低测试版本的可选库可能仍然可用,但不被视为受支持。

最低版本

已更改

pyarrow

7.0.0

X

matplotlib

3.6.1

X

fastparquet

0.6.3

X

xarray

0.21.0

X

有关更多信息,请参阅依赖项可选依赖项

日期时间现在以一致的格式解析#

过去,to_datetime() 会独立猜测每个元素的格式。这在某些元素具有混合日期格式的情况下是合适的——然而,当用户期望一致的格式但函数会在元素之间切换格式时,这通常会导致问题。从 2.0.0 版本开始,解析将使用一致的格式,由第一个非 NA 值决定(除非用户指定了格式,在这种情况下使用用户指定的格式)。

旧行为:

In [1]: ser = pd.Series(['13-01-2000', '12-01-2000'])
In [2]: pd.to_datetime(ser)
Out[2]:
0   2000-01-13
1   2000-12-01
dtype: datetime64[ns]

新行为:

In [42]: ser = pd.Series(['13-01-2000', '12-01-2000'])

In [43]: pd.to_datetime(ser)
Out[43]: 
0   2000-01-13
1   2000-01-12
dtype: datetime64[ns]

请注意,这也影响 read_csv()

如果您仍然需要解析格式不一致的日期,可以使用 format='mixed'(可能同时使用 dayfirst

ser = pd.Series(['13-01-2000', '12 January 2000'])
pd.to_datetime(ser, format='mixed', dayfirst=True)

或者,如果您的格式都是 ISO8601(但可能格式不完全相同)

ser = pd.Series(['2020-01-01', '2020-01-01 03:00'])
pd.to_datetime(ser, format='ISO8601')

其他 API 更改#

  • Timestamp 构造函数中的 freqtznanosecondunit 关键字现在是仅限关键字参数 (GH 45307, GH 32526)

  • Timestamp 中传入大于 999 或小于 0 的纳秒数现在会引发 ValueError (GH 48538, GH 48255)

  • read_csv():当使用 c 解析器时,使用 index_col 指定不正确的列数现在会引发 ParserError 而不是 IndexError

  • get_dummies()dtype 的默认值从 uint8 更改为 bool (GH 45848)

  • DataFrame.astype()Series.astype()DatetimeIndex.astype() 将 datetime64 数据转换为“datetime64[s]”、“datetime64[ms]”或“datetime64[us]”中的任何一个时,将返回具有给定分辨率的对象,而不是强制转换回“datetime64[ns]” (GH 48928)

  • DataFrame.astype()Series.astype()DatetimeIndex.astype() 将 timedelta64 数据转换为“timedelta64[s]”、“timedelta64[ms]”或“timedelta64[us]”中的任何一个时,将返回具有给定分辨率的对象,而不是强制转换为“float64”数据类型 (GH 48963)

  • DatetimeIndex.astype()TimedeltaIndex.astype()PeriodIndex.astype() Series.astype()DataFrame.astype() 在处理 datetime64timedelta64PeriodDtype 数据类型时,不再允许转换为除“int64”之外的整数数据类型,请改用 obj.astype('int64', copy=False).astype(dtype) (GH 49715)

  • Index.astype() 现在允许从 float64 数据类型转换为日期时间类数据类型,与 Series 行为一致 (GH 49660)

  • 将数据类型为“timedelta64[s]”、“timedelta64[ms]”或“timedelta64[us]”的数据传递给 TimedeltaIndexSeriesDataFrame 构造函数时,现在将保留该数据类型,而不是转换为“timedelta64[ns]”;分辨率较低的 timedelta64 数据将转换为最低支持的分辨率“timedelta64[s]” (GH 49014)

  • 将数据类型为“timedelta64[s]”、“timedelta64[ms]”或“timedelta64[us]”传递给 TimedeltaIndexSeriesDataFrame 构造函数时,现在将保留该数据类型,而不是转换为“timedelta64[ns]”;对于 SeriesDataFrame,传入分辨率较低的数据类型将转换为最低支持的分辨率“timedelta64[s]” (GH 49014)

  • 将非纳秒分辨率的 np.datetime64 对象传递给 Timestamp 将保留输入分辨率(如果是“s”、“ms”、“us”或“ns”);否则将转换为最接近的支持分辨率 (GH 49008)

  • 将分辨率非纳秒级的 datetime64 值传递给 to_datetime() 将保留输入分辨率(如果是“s”、“ms”、“us”或“ns”);否则将转换为最接近的支持分辨率 (GH 50369)

  • 将整数值和非纳秒级 datetime64 数据类型(例如“datetime64[s]”)传递给 DataFrameSeriesIndex 时,会将这些值视为数据类型单位的倍数,与例如 Series(np.array(values, dtype="M8[s]")) 的行为一致 (GH 51092)

  • 将 ISO-8601 格式的字符串传递给 Timestamp 将保留解析输入的分辨率(如果是“s”、“ms”、“us”或“ns”);否则将转换为最接近的支持分辨率 (GH 49737)

  • DataFrame.mask()Series.mask() 中的 other 参数现在默认值为 no_default 而不是 np.nan,这与 DataFrame.where()Series.where() 保持一致。条目将填充相应的 NULL 值(对于 NumPy 数据类型为 np.nan,对于扩展数据类型为 pd.NA)。(GH 49111)

  • Series.quantile()DataFrame.quantile()SparseDtype 的行为已更改,以保留稀疏数据类型 (GH 49583)

  • 当使用对象数据类型 Index 创建包含日期时间对象的 Series 时,pandas 不再默默地将索引转换为 DatetimeIndex (GH 39307, GH 23598)

  • pandas.testing.assert_index_equal() 使用参数 exact="equiv" 时,现在认为当两个索引都是 RangeIndex 或具有 int64 数据类型的 Index 时,它们是相等的。此前,这意味着 RangeIndexInt64Index (GH 51098)

  • 数据类型为 “timedelta64[ns]” 或 “datetime64[ns]” 的 Series.unique() 现在返回 TimedeltaArrayDatetimeArray,而不是 numpy.ndarray (GH 49176)

  • to_datetime()DatetimeIndex 现在允许包含 datetime 对象和数字条目的序列,与 Series 行为一致 (GH 49037, GH 50453)

  • pandas.api.types.is_string_dtype() 现在仅在元素被推断为字符串时,才对 dtype=object 的类数组返回 True (GH 15585)

  • 将包含 datetime 对象和 date 对象的序列传递给 Series 构造函数将返回 object 数据类型而不是 datetime64[ns] 数据类型,这与 Index 行为一致 (GH 49341)

  • 将无法解析为日期时间字符串的字符串传递给具有 dtype="datetime64[ns]"SeriesDataFrame 时,将引发错误而不是默默地忽略关键字并返回 object 数据类型 (GH 24435)

  • 将包含无法转换为 Timedelta 的类型的序列传递给 to_timedelta() 或传递给 SeriesDataFrame 构造函数(使用 dtype="timedelta64[ns]"),或传递给 TimedeltaIndex 时,现在会引发 TypeError 而不是 ValueError (GH 49525)

  • Index 构造函数在序列中包含至少一个 NaT 且其余均为 NoneNaN 时,其行为已更改为推断 datetime64[ns] 数据类型而不是 object,这与 Series 行为一致 (GH 49340)

  • read_stata() 在参数 index_col 设置为 None(默认值)时,现在将返回的 DataFrame 的索引设置为 RangeIndex 而不是 Int64Index (GH 49745)

  • IndexSeriesDataFrame 的算术方法在处理对象数据类型时,其行为已更改,结果不再对数组操作的结果进行类型推断;请使用 result.infer_objects(copy=False) 对结果进行类型推断 (GH 49999, GH 49714)

  • Index 构造函数在使用包含全布尔值或全复数值的对象数据类型 numpy.ndarray 时,其行为已更改,现在将保留对象数据类型,这与 Series 行为一致 (GH 49594)

  • Series.astype() 将包含 bytes 对象的数据类型从对象数据类型转换为字符串数据类型时,其行为已更改;现在对字节对象执行 val.decode() 而不是 str(val),这与 Index.astype() 行为一致 (GH 45326)

  • read_csv() 的默认 na_values 中添加了 "None" (GH 50286)

  • SeriesDataFrame 构造函数在给定整数数据类型和非整数浮点数据时,其行为已更改,现在会引发 ValueError 而不是默默地保留浮点数据类型;若要获得旧行为,请使用 Series(data)DataFrame(data);若要获得指定数据类型,请使用 Series(data).astype(dtype)DataFrame(data).astype(dtype) (GH 49599)

  • DataFrame.shift()axis=1、整数 fill_value 和同构日期时间类数据类型的情况下,其行为已更改,现在会用整数数据类型填充新列,而不是转换为日期时间类 (GH 49842)

  • read_json() 在遇到异常时现在会关闭文件 (GH 49921)

  • read_csv()read_json()read_fwf() 的行为已更改,现在在未指定索引时,索引将始终是 RangeIndex。此前,如果新的 DataFrame/Series 长度为 0,索引将是数据类型为 objectIndex (GH 49572)

  • DataFrame.values()DataFrame.to_numpy()DataFrame.xs()DataFrame.reindex()DataFrame.fillna()DataFrame.replace() 不再默默地整合底层数组;请使用 df = df.copy() 来确保整合 (GH 49356)

  • 使用 lociloc 在两个轴上进行完整切片(即 df.loc[:, :]df.iloc[:, :])创建新 DataFrame 时,现在会返回一个新的 DataFrame(浅拷贝),而不是原始 DataFrame,这与其他获取完整切片的方法(例如 df.loc[:]df[:])保持一致 (GH 49469)

  • SeriesDataFrame 构造函数在分别传入 Series 和 DataFrame 且默认 copy=False(且没有其他关键字触发复制)时,现在将返回一个浅拷贝(即共享数据,但不共享属性)。此前,新的 Series 或 DataFrame 会共享索引属性(例如,df.index = ... 也会更新父级或子级的索引)(GH 49523)

  • 禁止计算 Timedelta 对象的 cumprod;此前这会返回不正确的值 (GH 50246)

  • HDFStore 文件中读取的没有索引的 DataFrame 对象现在具有 RangeIndex 而不是 int64 索引 (GH 51076)

  • 使用包含 NA 和/或 NaT 的数据实例化数字 NumPy 数据类型的 Index 现在会引发 ValueError。此前会引发 TypeError (GH 51050)

  • 使用 read_json(orient='split') 加载具有重复列的 JSON 文件时,现在会重命名列以避免重复,这与 read_csv() 和其他读取器一致 (GH 50370)

  • Series.sparse.from_coo 返回的 Series 的索引级别现在始终具有数据类型 int32。此前它们的数据类型为 int64 (GH 50926)

  • to_datetime()unit 为 “Y” 或 “M” 且序列包含非整数 float 值时,现在会引发错误,这与 Timestamp 行为一致 (GH 50301)

  • Series.round()DataFrame.__invert__()Series.__invert__()DataFrame.swapaxes()DataFrame.first()DataFrame.last()Series.first()Series.last()DataFrame.align() 方法现在将始终返回新对象 (GH 51032)

  • DataFrameDataFrameGroupBy 聚合(例如 “sum”)在处理对象数据类型列时,不再为其结果推断非对象数据类型,请显式地在结果上调用 result.infer_objects(copy=False) 以获得旧行为 (GH 51205, GH 49603)

  • 使用 ArrowDtype 数据类型进行除以零操作时,根据分子,现在返回 -infnaninf,而不是引发错误 (GH 51541)

  • 添加了 pandas.api.types.is_any_real_numeric_dtype() 以检查实际数字数据类型 (GH 51152)

  • value_counts() 现在返回数据类型为 ArrowDtype 且类型为 pyarrow.int64 的数据,而不是 "Int64" 类型 (GH 51462)

  • factorize()unique() 在传入非纳秒分辨率的 NumPy timedelta64 或 datetime64 时,会保留原始数据类型 (GH 48670)

注意

当前的 PDEP 提案废弃并移除 pandas API 中除一小部分方法外的所有 inplacecopy 关键字。目前的讨论正在 此处 进行。在写时复制 (Copy-on-Write) 的背景下,这些关键字将不再是必需的。如果此提案被接受,这两个关键字将在 pandas 的下一个版本中被废弃,并在 pandas 3.0 中移除。

弃用#

移除先前版本的弃用/更改#

性能改进#

错误修复#

Categorical#

日期时间类型#

时间差#

  • to_timedelta() 中存在一个 Bug,当输入具有可空数据类型 Float64 时会抛出错误(GH 48796

  • Timedelta 构造函数中的错误:当给定 np.timedelta64("nat") 时,错误地抛出异常而不是返回 NaT (GH 48898)

  • Timedelta 构造函数中的错误:当同时传入 Timedelta 对象和关键字(如 days, seconds)时未能抛出异常 (GH 48898)

  • Timedelta 与非常大的 datetime.timedelta 对象进行比较时,错误地引发 OutOfBoundsTimedelta 的错误 (GH 49021)

时区#

  • Series.astype()DataFrame.astype() 中的错误:当 object-dtype 包含多个时区感知(timezone-aware)的 datetime 对象且时区不一致时,将其转换为 DatetimeTZDtype 会错误地引发异常 (GH 32581)

  • to_datetime() 中的错误:当 format 使用 %Z 指定时,未能解析带有时区名称的日期字符串 (GH 49748)

  • 改进了当 Timestamp.tz_localize()ambiguous 参数传入无效值时的错误消息 (GH 49565)

  • 字符串解析中的错误:错误地允许使用无效时区构造 Timestamp,这会在尝试打印时引发异常 (GH 50668)

  • 修正了 objects_to_datetime64ns() 中的 TypeError 消息,以提示 DatetimeIndex 具有混合时区 (GH 50974)

数值#

转换#

字符串#

  • pandas.api.types.is_string_dtype() 中的错误:当数据类型为 StringDtype 或带有 pyarrow.string()ArrowDtype 时,不会返回 True (GH 15585)

  • 将字符串数据类型转换为“datetime64[ns]”或“timedelta64[ns]”时,错误地引发 TypeError 的错误 (GH 36153)

  • 在字符串数据类型列中用数组设置值时,当数组包含缺失值时,作为副作用会修改数组的错误 (GH 51299)

区间#

索引#

  • DataFrame.__setitem__() 中的错误:当索引器是 boolean 数据类型的 DataFrame 时引发异常 (GH 47125)

  • DataFrame.reindex() 中的错误:当索引列和索引为 uint 数据类型时,填充了错误的值 (GH 48184)

  • DataFrame.loc() 中的错误:当设置具有不同数据类型的 DataFrame 时,会将值强制转换为单一数据类型 (GH 50467)

  • DataFrame.sort_values() 中的错误:当 by 为空列表且 inplace=True 时,未返回 None (GH 50643)

  • DataFrame.loc() 中的错误:当使用列表索引器设置值时,强制转换数据类型 (GH 49159)

  • Series.loc() 中的错误:对超出范围的切片结束索引器引发错误 (GH 50161)

  • DataFrame.loc() 中的错误:当使用全 Falsebool 索引器和空对象时,引发 ValueError (GH 51450)

  • DataFrame.loc() 中的错误:当使用 bool 索引器和 MultiIndex 时,引发 ValueError (GH 47687)

  • DataFrame.loc() 中的错误:当使用非标量索引器设置 pyarrow 后端列的值时,引发 IndexError (GH 50085)

  • DataFrame.__getitem__()Series.__getitem__()DataFrame.__setitem__()Series.__setitem__() 中的错误:当对具有扩展浮点数据类型(Float64 & Float64)或使用整数的复杂数据类型的索引进行索引时 (GH 51053)

  • DataFrame.loc() 中的错误:当使用空索引器设置不兼容值时修改对象 (GH 45981)

  • DataFrame.__setitem__() 中的错误:当右侧是具有 MultiIndex 列的 DataFrame 时,引发 ValueError (GH 49121)

  • DataFrame.reindex() 中的错误:当 DataFrame 具有单个扩展数组列且对 columnsindex 进行重新索引时,将数据类型强制转换为 object (GH 48190)

  • DataFrame.iloc() 中的错误:当索引器是具有数值扩展数组数据类型的 Series 时,引发 IndexError (GH 49521)

  • describe() 中的错误:在结果索引中格式化百分位数时,显示了比所需更多的小数位 (GH 46362)

  • DataFrame.compare() 中的错误:当比较可空数据类型中的 NA 与值时,不识别差异 (GH 48939)

  • Series.rename() 中的错误:当使用 MultiIndex 时丢失扩展数组数据类型 (GH 21055)

  • DataFrame.isetitem() 中的错误:将 DataFrame 中的扩展数组数据类型强制转换为 object 类型 (GH 49922)

  • Series.__getitem__() 中的错误:当从空的 pyarrow 后端对象中选择时返回损坏的对象 (GH 51734)

  • BusinessHour 中的错误:当索引中不包含开放时间时,会导致 DatetimeIndex 创建失败 (GH 49835)

缺失值#

  • Index.equals() 中的错误:当 Index 由包含 NA 的元组组成时,引发 TypeError (GH 48446)

  • Series.map() 中的错误:当数据包含 NaN 且使用了 defaultdict 映射时,导致结果不正确 (GH 48813)

  • NA 中的错误:当与 bytes 对象执行二进制操作时,引发 TypeError 而不是返回 NA (GH 49108)

  • DataFrame.update() 中的错误:当 overwrite=Falseself 具有包含 NaT 值的列但该列在 other 中不存在时,引发 TypeError (GH 16713)

  • Series.replace() 中的错误:当替换包含 NA 的 object-dtype Series 中的值时,引发 RecursionError (GH 47480)

  • Series.replace() 中的错误:当替换包含 NA 的数值 Series 中的值时,引发 RecursionError (GH 50758)

多级索引#

输入/输出#

周期#

  • Period.strftime()PeriodIndex.strftime() 中的错误:当传入特定于语言环境的指令时,引发 UnicodeDecodeError (GH 46319)

  • Period 对象添加到 DateOffset 对象数组时,错误地引发 TypeError 的错误 (GH 50162)

  • Period 中的错误:当传入精度高于纳秒的字符串时,会导致 KeyError,而不是丢弃额外精度 (GH 50417)

  • 解析表示周期的字符串(例如“2017-01-23/2017-01-29”)时,错误地将其解析为分钟频率而不是周频率的错误 (GH 50803)

  • DataFrameGroupBy.sum(), DataFrameGroupByGroupBy.cumsum(), DataFrameGroupByGroupBy.prod(), DataFrameGroupByGroupBy.cumprod() 中的错误:当使用 PeriodDtype 时,未能引发 TypeError (GH 51040)

  • 解析空字符串时,Period 错误地引发 ValueError 而不是返回 NaT 的错误 (GH 51349)

绘图#

  • DataFrame.plot.hist() 中的错误:未丢弃 data 中对应 NaN 值的 weights 元素 (GH 48884)

  • ax.set_xlim 有时会引发 UserWarning,用户无法解决,因为 set_xlim 不接受解析参数——转换器现在改为使用 Timestamp() (GH 49148)

分组/重采样/滚动#

重塑#

稀疏#

扩展数组#

Styler#

元数据#

其他#

贡献者#

共有260人次为本次发布贡献了补丁。名字旁带有“+”的人是首次贡献补丁。

  • 5j9 +

  • ABCPAN-rank +

  • Aarni Koskela +

  • Aashish KC +

  • Abubeker Mohammed +

  • Adam Mróz +

  • Adam Ormondroyd +

  • Aditya Anulekh +

  • Ahmed Ibrahim

  • Akshay Babbar +

  • Aleksa Radojicic +

  • Alex +

  • Alex Buzenet +

  • Alex Kirko

  • Allison Kwan +

  • Amay Patel +

  • Ambuj Pawar +

  • Amotz +

  • Andreas Schwab +

  • Andrew Chen +

  • Anton Shevtsov

  • Antonio Ossa Guerra +

  • Antonio Ossa-Guerra +

  • Anushka Bishnoi +

  • Arda Kosar

  • Armin Berres

  • Asadullah Naeem +

  • Asish Mahapatra

  • Bailey Lissington +

  • BarkotBeyene

  • Ben Beasley

  • Bhavesh Rajendra Patil +

  • Bibek Jha +

  • Bill +

  • Bishwas +

  • CarlosGDCJ +

  • Carlotta Fabian +

  • Chris Roth +

  • Chuck Cadman +

  • Corralien +

  • DG +

  • Dan Hendry +

  • Daniel Isaac

  • David Kleindienst +

  • David Poznik +

  • David Rudel +

  • DavidKleindienst +

  • Dea María Léon +

  • Deepak Sirohiwal +

  • Dennis Chukwunta

  • Douglas Lohmann +

  • Dries Schaumont

  • Dustin K +

  • Edoardo Abati +

  • Eduardo Chaves +

  • Ege Özgüroğlu +

  • Ekaterina Borovikova +

  • Eli Schwartz +

  • Elvis Lim +

  • Emily Taylor +

  • Emma Carballal Haire +

  • Erik Welch +

  • Fangchen Li

  • Florian Hofstetter +

  • Flynn Owen +

  • Fredrik Erlandsson +

  • Gaurav Sheni

  • Georeth Chow +

  • George Munyoro +

  • Guilherme Beltramini

  • Gulnur Baimukhambetova +

  • H L +

  • Hans

  • Hatim Zahid +

  • HighYoda +

  • Hiki +

  • Himanshu Wagh +

  • Hugo van Kemenade +

  • Idil Ismiguzel +

  • Irv Lustig

  • Isaac Chung

  • Isaac Virshup

  • JHM Darbyshire

  • JHM Darbyshire (iMac)

  • JMBurley

  • Jaime Di Cristina

  • Jan Koch

  • JanVHII +

  • Janosh Riebesell

  • JasmandeepKaur +

  • Jeremy Tuloup

  • Jessica M +

  • Jonas Haag

  • Joris Van den Bossche

  • João Meirelles +

  • Julia Aoun +

  • Justus Magin +

  • Kang Su Min +

  • Kevin Sheppard

  • Khor Chean Wei

  • Kian Eliasi

  • Kostya Farber +

  • KotlinIsland +

  • Lakmal Pinnaduwage +

  • Lakshya A Agrawal +

  • Lawrence Mitchell +

  • Levi Ob +

  • Loic Diridollou

  • Lorenzo Vainigli +

  • Luca Pizzini +

  • Lucas Damo +

  • Luke Manley

  • Madhuri Patil +

  • Marc Garcia

  • Marco Edward Gorelli

  • Marco Gorelli

  • MarcoGorelli

  • Maren Westermann +

  • Maria Stazherova +

  • Marie K +

  • Marielle +

  • Mark Harfouche +

  • Marko Pacak +

  • Martin +

  • Matheus Cerqueira +

  • Matheus Pedroni +

  • Matteo Raso +

  • Matthew Roeschke

  • MeeseeksMachine +

  • Mehdi Mohammadi +

  • Michael Harris +

  • Michael Mior +

  • Natalia Mokeeva +

  • Neal Muppidi +

  • Nick Crews

  • Nishu Choudhary +

  • Noa Tamir

  • Noritada Kobayashi

  • Omkar Yadav +

  • P. Talley +

  • Pablo +

  • Pandas Development Team

  • Parfait Gasana

  • Patrick Hoefler

  • Pedro Nacht +

  • Philip +

  • Pietro Battiston

  • Pooja Subramaniam +

  • Pranav Saibhushan Ravuri +

  • Pranav. P. A +

  • Ralf Gommers +

  • RaphSku +

  • Richard Shadrach

  • Robsdedude +

  • Roger

  • Roger Thomas

  • RogerThomas +

  • SFuller4 +

  • Salahuddin +

  • Sam Rao

  • Sean Patrick Malloy +

  • Sebastian Roll +

  • Shantanu

  • Shashwat +

  • Shashwat Agrawal +

  • Shiko Wamwea +

  • Shoham Debnath

  • Shubhankar Lohani +

  • Siddhartha Gandhi +

  • Simon Hawkins

  • Soumik Dutta +

  • Sowrov Talukder +

  • Stefanie Molin

  • Stefanie Senger +

  • Stepfen Shawn +

  • Steven Rotondo

  • Stijn Van Hoey

  • Sudhansu +

  • Sven

  • Sylvain MARIE

  • Sylvain Marié

  • Tabea Kossen +

  • Taylor Packard

  • Terji Petersen

  • Thierry Moisan

  • Thomas H +

  • Thomas Li

  • Torsten Wörtwein

  • Tsvika S +

  • Tsvika Shapira +

  • Vamsi Verma +

  • Vinicius Akira +

  • William Andrea

  • William Ayd

  • William Blum +

  • Wilson Xing +

  • Xiao Yuan +

  • Xnot +

  • Yasin Tatar +

  • Yuanhao Geng

  • Yvan Cywan +

  • Zachary Moon +

  • Zhengbo Wang +

  • abonte +

  • adrienpacifico +

  • alm

  • amotzop +

  • andyjessen +

  • anonmouse1 +

  • bang128 +

  • bishwas jha +

  • calhockemeyer +

  • carla-alves-24 +

  • carlotta +

  • casadipietra +

  • catmar22 +

  • cfabian +

  • codamuse +

  • dataxerik

  • davidleon123 +

  • dependabot[bot] +

  • fdrocha +

  • github-actions[bot]

  • himanshu_wagh +

  • iofall +

  • jakirkham +

  • jbrockmendel

  • jnclt +

  • joelchen +

  • joelsonoda +

  • joshuabello2550

  • joycewamwea +

  • kathleenhang +

  • krasch +

  • ltoniazzi +

  • luke396 +

  • milosz-martynow +

  • minat-hub +

  • mliu08 +

  • monosans +

  • nealxm

  • nikitaved +

  • paradox-lab +

  • partev

  • raisadz +

  • ram vikram singh +

  • rebecca-palmer

  • sarvaSanjay +

  • seljaks +

  • silviaovo +

  • smij720 +

  • soumilbaldota +

  • stellalin7 +

  • strawberry beach sandals +

  • tmoschou +

  • uzzell +

  • yqyqyq-W +

  • yun +

  • Ádám Lippai

  • 김동현 (Daniel Donghyun Kim) +