2.0.0 中的新增功能(2023 年 4 月 3 日)#

这些是 pandas 2.0.0 中的变化。请参阅发行说明以获取完整的变更日志,包括其他版本的 pandas。

增强功能#

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

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

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

安装指南中提供的可用附加功能为 ( GH 39164 )。[all, performance, computation, fss, aws, gcp, excel, parquet, feather, hdf5, spss, postgresql, mysql, sql-other, html, xml, plot, output_formatting, clipboard, compression, test]

Index现在可以保存 numpy 数字 dtypes #

现在可以在Index( GH 42717 ) 中使用任何 numpy 数字 dtype。

以前只能使用int64, uint64& float64dtypes:

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")

Int64Index, UInt64Index&Float64Index在 pandas 1.4 版本中已弃用,现已被删除。相反,Index应该直接使用,并且现在可以采用所有 numpy 数字 dtypes,即 int8/ int16/ int32/ int64/ uint8/ uint16/ uint32/ uint64/ float32/ float64dtypes:

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')

保存 numpy 数字数据类型的能力Index意味着 Pandas 功能发生了一些变化。特别是,以前被迫创建 64 位索引的操作现在可以创建具有较低位大小的索引,例如 32 位索引。

以下是可能不完整的更改列表:

  1. 现在使用 numpy 数值数组实例化遵循 numpy 数组的 dtype。以前,从 numpy 数值数组创建的所有索引都被强制为 64 位。例如,现在将在 32 位系统上运行,而以前甚至在 32 位系统上运行。使用数字列表实例化仍将返回 64 位 dtype,例如将具有与之前相同的 dtype。Index(np.array([1, 2, 3]))int32int64IndexIndex([1, 2, 3])int64

  2. DatetimeIndex( daymonth等)的各种数字日期时间属性year以前属于 dtype int64,而现在int32属于arrays.DatetimeArray.他们现在 int32DatetimeIndex

    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. 索引上的级别 dtypeSeries.sparse.from_coo()现在为 dtype ,与scipy 稀疏矩阵上的/int32相同。以前它们是 dtype 。rowscolsint64

    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 数据类型实例化。之前实例化Indexusing dtypefloat16会导致Float64Index使用 dtype 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:576, in Index.__new__(cls, data, dtype, copy, name, tupleize_cols)
        572 arr = ensure_wrapped_if_datetimelike(arr)
        574 klass = cls._dtype_to_subclass(arr.dtype)
    --> 576 arr = klass._ensure_array(arr, arr.dtype, copy=False)
        577 result = klass._simple_new(arr, name, refs=refs)
        578 if dtype is None and is_pandas_object and data_dtype == np.object_:
    
    File ~/work/pandas/pandas/pandas/core/indexes/base.py:601, in Index._ensure_array(cls, data, dtype, copy)
        598     raise ValueError("Index data must be 1-dimensional")
        599 elif dtype == np.float16:
        600     # float16 not supported (no indexing engine)
    --> 601     raise NotImplementedError("float16 indexes are not supported")
        603 if copy:
        604     # asarray_tuplesafe does not always copy underlying data,
        605     #  so need to make sure that this happens
        606     data = data.copy()
    
    NotImplementedError: float16 indexes are not supported
    

参数dtype_backend,返回 pyarrow-backed 或 numpy-backed nullable dtypes #

以下函数获得了新关键字dtype_backendGH 36712

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

当此关键字设置为 时"pyarrow",这些函数将返回 pyarrow 支持的可空ArrowDtypeDataFrame(GH 48957GH 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 ) 相比,这提供了显着的性能改进。

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

  • 当从现有系列构造系列时,构造Series函数现在将创建一个惰性副本(推迟复制,直到发生数据修改),默认值为copy=FalseGH 50471

  • 当从现有的默认值(GH 51239)构建时,构造DataFrame函数现在将创建一个惰性副本(推迟复制,直到发生数据修改) DataFramecopy=False

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

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

  • 当从 NumPy 数组构造时,和构造函数现在将默认复制数组,以避免DataFrame在 改变数组时改变/ 。指定获取旧行为。当创建 /后修改 NumPy 数组时,设置pandas 并不能保证正确的 Copy-on-Write 行为。SeriesDataFrameSeriescopy=Falsecopy=FalseDataFrameSeries

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

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

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

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

  • 可以就地进行的算术运算现在将遵循写入时复制机制。ser *= 2

  • DataFrame.__getitem__()DataFrame当有列时,现在将遵循写入时复制机制 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()溢出而不是有损转换为浮动#

在以前的版本中,我们在应用时强制转换为 float cumsumcumprod这会导致错误的结果,即使结果可以由int64dtype 保存。此外,当达到的限制时, 聚合溢出与 numpy 和常规方法一致 DataFrame.cumprod()GH 37493)。DataFrame.cumsum()int64

旧行为

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 dtype 进行构造,分辨率不受支持#

在过go的版本中,当构造SeriesorDataFrame并传递具有不支持的分辨率(即“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:651, in sanitize_array(data, index, dtype, copy, allow_2d)
    648     subarr = np.array([], dtype=np.float64)
    650 elif dtype is not None:
--> 651     subarr = _try_cast(data, dtype, copy)
    653 else:
    654     subarr = maybe_convert_platform(data)

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

File ~/work/pandas/pandas/pandas/core/dtypes/cast.py:1219, in maybe_cast_to_datetime(value, dtype)
   1215     raise TypeError("value must be listlike")
   1217 # TODO: _from_sequence would raise ValueError in cases where
   1218 #  _ensure_nanosecond_dtype raises TypeError
-> 1219 _ensure_nanosecond_dtype(dtype)
   1221 if lib.is_np_dtype(dtype, "m"):
   1222     res = TimedeltaArray._from_sequence(value, dtype=dtype)

File ~/work/pandas/pandas/pandas/core/dtypes/cast.py:1276, in _ensure_nanosecond_dtype(dtype)
   1273     raise ValueError(msg)
   1274 # TODO: ValueError or TypeError? existing test
   1275 #  test_constructor_generic_timestamp_bad_frequency expects TypeError
-> 1276 raise TypeError(
   1277     f"dtype={dtype} is not supported. Supported resolutions are 's', "
   1278     "'ms', 'us', and 'ns'"
   1279 )

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

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

在过go的版本中,运行时Series.value_counts(),结果将继承原始对象的名称,并且结果索引将是无名的。这会在重置索引时造成混乱,并且列名与列值不对应。现在,结果名称将为'count'(或者'proportion'如果已传递),并且索引将以原始对象( GH 49497normalize=True )命名。

以前的行为

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 dtypes #

在以前的版本中,将 aSeriesDataFrame from转换datetime64[ns]为不同的datetime64[X]dtype 将返回datetime64[ns]dtype 而不是请求的 dtype。在 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:6643, in NDFrame.astype(self, dtype, copy, errors)
   6637     results = [
   6638         ser.astype(dtype, copy=copy, errors=errors) for _, ser in self.items()
   6639     ]
   6641 else:
   6642     # else, only a single dtype is given
-> 6643     new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors)
   6644     res = self._constructor_from_mgr(new_data, axes=new_data.axes)
   6645     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:758, in Block.astype(self, dtype, copy, errors, using_cow, squeeze)
    755         raise ValueError("Can not squeeze with more than one column.")
    756     values = values[0, :]  # type: ignore[call-overload]
--> 758 new_values = astype_array_safe(values, dtype, copy=copy, errors=errors)
    760 new_values = maybe_coerce_values(new_values)
    762 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:739, in DatetimeArray.astype(self, dtype, copy)
    737 elif isinstance(dtype, PeriodDtype):
    738     return self.to_period(freq=dtype.freq)
--> 739 return dtl.DatetimeLikeArrayMixin.astype(self, dtype, copy)

File ~/work/pandas/pandas/pandas/core/arrays/datetimelike.py:494, in DatetimeLikeArrayMixin.astype(self, dtype, copy)
    490 elif (dtype.kind in "mM" and self.dtype != dtype) or dtype.kind == "f":
    491     # disallow conversion between datetime/timedelta,
    492     # and conversions for any datetimelike to float
    493     msg = f"Cannot cast {type(self).__name__} to dtype {dtype}"
--> 494     raise TypeError(msg)
    495 else:
    496     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,新行为要么准确给出请求的 dtype,要么引发:

新行为

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:6643, in NDFrame.astype(self, dtype, copy, errors)
   6637     results = [
   6638         ser.astype(dtype, copy=copy, errors=errors) for _, ser in self.items()
   6639     ]
   6641 else:
   6642     # else, only a single dtype is given
-> 6643     new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors)
   6644     res = self._constructor_from_mgr(new_data, axes=new_data.axes)
   6645     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:758, in Block.astype(self, dtype, copy, errors, using_cow, squeeze)
    755         raise ValueError("Can not squeeze with more than one column.")
    756     values = values[0, :]  # type: ignore[call-overload]
--> 758 new_values = astype_array_safe(values, dtype, copy=copy, errors=errors)
    760 new_values = maybe_coerce_values(new_values)
    762 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 对象#

tzinfo在以前的版本中,用于表示 UTC 的默认对象是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 也不是固定偏移量的时区,例如“美国/太平洋”,我们继续默认为pytz对象。

空数据框/系列现在默认有RangeIndex#

之前,构造一个空(其中dataisNone或类似空列表的参数)SeriesDataFrame不指定轴 ( index=None, columns=None) 会将轴返回为Index具有对象 dtype 的空。

现在,轴返回空值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 to 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.multicolumn,display.latex.multicolumn_formatdisplay.latex.multirow: 替换为styler.sparse.rows, styler.sparse.columns,styler.latex.multirow_alignstyler.latex.multicol_align,

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

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

请注意,由于此更改,一些默认值也发生了变化:

  • multirow现在默认为True

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

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

  • escape现在默认为False

请注意, 的行为_repr_latex_也发生了变化。以前的设置display.latex.repr仅在对 JupyterNotebook 使用 nbconvert 时生成 LaTeX,而不是在用户运行笔记本时生成 LaTeX。现在,该 styler.render.repr选项允许控制 JupyterNotebooks 中的特定输出以进行操作(不仅仅是在 nbconvert 上)。参见GH 39911

增加了依赖项的最低版本#

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

包裹

最低版本

必需的

改变了

mypy(开发)

1.0

X

pytest(开发)

7.0.0

X

pytest-xdist(开发)

2.2.0

X

假设(开发)

6.34.2

X

python-dateutil

2.8.2

X

X

兹数据

2022.1

X

X

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

包裹

最低版本

改变了

皮箭头

7.0.0

X

绘图库

3.6.1

X

快速镶木地板

0.6.3

X

阵列

0.21.0

X

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

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

过go,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 更改#

  • 构造函数中的freqtznanosecond和关键字现在仅是关键字(GH 45307GH 32526unitTimestamp

  • 现在传递nanoseconds大于 999 或小于 0Timestamp会引发ValueError( GH 48538 , GH 48255 )

  • read_csv()index_col:使用of now指定错误的列数ParserError而不是IndexError使用 c 解析器时会引发。

  • dtypein的默认值get_dummies()更改为boolfrom uint8( 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”dtype ( GH 48963 )

  • DatetimeIndex.astype()TimedeltaIndex.astype()PeriodIndex.astype() Series.astype()DataFrame.astype()withdatetime64或dtypes 不再允许转换为除“int64”之外的整数 dtypes,请timedelta64改为( GH 49715 )PeriodDtypeobj.astype('int64', copy=False).astype(dtype)

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

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

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

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

  • 如果输入分辨率为“s”、“ms”、“us”或“ns”,则传递datetime64除纳秒以外的分辨率的值将保留输入分辨率;to_datetime()否则它将被投射到最接近的支持分辨率(GH 50369

  • 传递整数值和非纳秒 datetime64 dtype(例如“datetime64[s]”)DataFrameSeriesIndex会将值视为 dtype 单位的倍数,匹配例如(GH 51092)的行为Series(np.array(values, dtype="M8[s]"))

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

  • andother中的参数现在默认为与and一致。条目将填充相应的 NULL 值(对于 numpy 数据类型,对于扩展数据类型)。 (GH 49111DataFrame.mask()Series.mask()no_defaultnp.nanDataFrame.where()Series.where()np.nanpd.NA

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

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

  • pandas.testing.assert_index_equal()exact="equiv"现在,当两个索引都是 aRangeIndexIndex具有dtype 时,with 参数认为两个索引相等int64。以前它意味着 aRangeIndex或 a Int64Index( GH 51098 )

  • Series.unique()dtype“timedelta64[ns]”或“datetime64[ns]”现在返回TimedeltaArrayDatetimeArray代替numpy.ndarrayGH 49176

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

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

  • datetime将包含对象和对象的序列传递dateSeries构造函数将返回objectdtype 而不是datetime64[ns]dtype,与Index行为一致(GH 49341

  • 将无法解析为日期时间的字符串传递给SeriesDataFramedtype="datetime64[ns]"将引发,而不是默默地忽略关键字并返回objectdtype ( GH 24435 )

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

  • 更改了构造函数的行为Index,序列包含至少一个NaT和其他所有内容,None或者NaN推断datetime64[ns]dtype 而不是object匹配Series行为(GH 49340

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

  • 使用对象数据类型时更改了 、 和算术方法的行为,结果不再对数组操作的结果进行类型推断,而是用于IndexSeries结果进行类型推断(GH 49999GH 49714DataFrameresult.infer_objects(copy=False)

  • 更改了包含所有值或所有复杂值的Index对象数据类型的构造函数的行为,这现在将保留对象数据类型,与行为一致(GH 49594numpy.ndarrayboolSeries

  • Series.astype()将包含对象的对象数据类型更改bytes为字符串数据类型;现在,这val.decode()对字节对象执行,而不是str(val)匹配Index.astype()行为(GH 45326

  • 添加"None"到默认值na_values( read_csv()GH 50286 )

  • 当给定整数数据类型和非整数的浮点数据时,更改了Series和构造函数的行为,现在会引发而不是默默地保留浮点数据类型;执行or获取旧行为,或者获取指定的 dtype ( GH 49599 )DataFrameValueErrorSeries(data)DataFrame(data)Series(data).astype(dtype)DataFrame(data).astype(dtype)

  • DataFrame.shift()更改了with axis=1、 integer和同质 datetime-like dtype的行为fill_value,现在用整数 dtypes 填充新列,而不是转换为 datetimelike ( GH 49842 )

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

  • read_csv()更改了, read_json()&的行为,当未指定索引时,read_fwf()索引现在始终为 a 。以前,如果新 DataFrame/Series 的长度为 0 ( GH 49572 ),RangeIndex则索引将为Indexdtypeobject

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

  • loc 使用or iloc(因此,或)在两个轴上使用完整切片创建新的 DataFrame现在返回一个新的 DataFrame (浅拷贝)而不是原始 DataFrame,与获取完整切片的其他方法一致(例如或)( GH 49469df.loc[:, :]df.iloc[:, :]df.loc[:]df[:]

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

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

  • DataFrameHDFStore从没有索引的文件读取的对象现在有一个RangeIndex而不是int64索引(GH 51076

  • 使用包含和/或现在的Index数据的数字 numpy dtype实例化 an会引发.之前提出了 a ( GH 51050 )NANaTValueErrorTypeError

  • 使用重命名列来加载包含重复列的 JSON 文件read_json(orient='split')以避免重复,就像read_csv()其他读者所做的那样 ( GH 50370 )

  • Series从现在开始返回的索引的级别Series.sparse.from_coo始终具有 dtype int32。以前他们有 dtype 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 )

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

  • ArrowDtypedtypes 除以零会返回-inf, nan, 或 ,inf具体取决于分子,而不是提高 ( GH 51541 )

  • 添加pandas.api.types.is_any_real_numeric_dtype()以检查真实数字 dtypes ( GH 51152 )

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

  • factorize()unique()在以非纳秒分辨率传递 numpy timedelta64 或 datetime64 时保留原始数据类型(GH 48670

笔记

当前的 PDEP 建议弃用和删除关键字inplace以及copy pandas API 中除一小部分方法之外的所有方法。当前的讨论就在这里进行。在写入时复制的上下文中不再需要关键字。如果该提案被接受,这两个关键字将在 pandas 的下一个版本中被弃用,并在 pandas 3.0 中删除。

弃用#

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

性能改进#

Bug修复

分类#

类似日期时间#

时间增量#

  • to_timedelta()当输入具有可为空的数据类型时引发错误的错误Float64GH 48796

  • 构造函数中的错误在给定 a 时Timedelta错误地引发而不是返回(GH 48898NaTnp.timedelta64("nat")

  • 当传递对象和关键字(例如天、秒)时,构造函数中的错误Timedelta无法引发( GH 48898Timedelta

  • Timedelta与非常大的datetime.timedelta对象进行比较时的错误错误提升OutOfBoundsTimedeltaGH 49021

时区

数字#

转换

字符串#

间隔

索引#

丢失的

多重索引#

输入/输出#

时期

  • Period.strftime()和中的错误,在传递特定于区域设置的指令时PeriodIndex.strftime()引发( GH 46319UnicodeDecodeError

  • 将对象添加到对象Period数组时DateOffset错误地引发错误TypeErrorGH 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而不是返回NaTGH 51349

绘图#

  • 错误DataFrame.plot.hist(),没有删除与(GH 48884)中的值weights相对应的元素NaNdata

  • ax.set_xlim有时会引发用户由于不接受解析参数而UserWarning无法解决的问题 - 转换器现在使用(GH 49148set_xlimTimestamp()

分组/重新采样/滚动#

重塑#

稀疏#

扩展数组#

造型器#

元数据#

其他

贡献者#

共有 260 人为此版本贡献了补丁。名字带有“+”的人首次贡献了补丁。

  • 5j9+

  • ABCPAN 等级 +

  • 阿尼·科斯克拉 +

  • 阿什什 KC +

  • 阿布贝克·穆罕默德 +

  • 亚当·姆罗兹 +

  • 亚当·奥蒙德罗伊德 +

  • 阿迪亚·阿努莱克 +

  • 艾哈迈德·易卜拉欣

  • 阿克谢·巴巴尔 +

  • 阿列克萨·拉多吉西奇 +

  • 亚历克斯+

  • 亚历克斯·布泽内特 +

  • 亚历克斯·科科

  • 关佳丽 +

  • 阿梅·帕特尔 +

  • 安布吉·帕瓦尔 +

  • 阿莫兹+

  • 安德烈亚斯·施瓦布 +

  • 安德鲁·陈 +

  • 安东·舍夫佐夫

  • 安东尼奥·奥萨·格拉 +

  • 安东尼奥·奥萨-格拉 +

  • 安努舒卡·比什诺伊 +

  • 阿尔达·科萨尔

  • 阿明·贝尔雷斯

  • 阿萨杜拉·纳伊姆 +

  • 阿希·玛哈帕特拉

  • 贝利·利辛顿 +

  • 巴科特·贝耶内

  • 本·比斯利

  • 巴韦什·拉金德拉·帕蒂尔 +

  • 比贝克·贾 +

  • 比尔+

  • 比什瓦斯 +

  • 卡洛斯GDCJ +

  • 卡洛塔·法比安 +

  • 克里斯·罗斯 +

  • 查克·卡德曼 +

  • 科拉林+

  • 副局长+

  • 丹·亨德利 +

  • 丹尼尔·艾萨克

  • 大卫·克莱因丁斯特 +

  • 大卫·波兹尼克 +

  • 大卫·鲁德尔 +

  • 大卫·克莱因丁斯特 +

  • 德亚·玛丽亚·莱昂 +

  • 迪帕克·西罗希瓦尔 +

  • 丹尼斯·查昆塔

  • 道格拉斯·洛曼 +

  • 德里斯·肖蒙

  • 达斯汀·K+

  • 爱德华多·阿巴蒂 +

  • 爱德华多·查韦斯 +

  • 埃格·厄兹古罗格鲁 +

  • 叶卡捷琳娜·博罗维科娃 +

  • 伊莱·施瓦茨 +

  • 林埃尔维斯 +

  • 艾米丽·泰勒 +

  • 艾玛·卡巴拉尔·海尔 +

  • 埃里克·韦尔奇 +

  • 李芳辰

  • 弗洛里安·霍夫施泰特 +

  • 弗林·欧文 +

  • 弗雷德里克·埃兰森 +

  • 高拉夫·谢尼

  • 乔雷·周 +

  • 乔治·蒙约罗 +

  • 吉列尔梅·贝尔特拉米尼

  • 古努尔·拜姆坎贝托娃 +

  • HL+

  • 汉斯

  • 哈蒂姆·扎希德 +

  • 高尤达+

  • 比企+

  • 希曼舒·瓦格 +

  • 雨果·范·凯梅纳德 +

  • 伊迪尔·伊斯米古泽尔 +

  • 欧夫·勒斯蒂格

  • 艾萨克·钟

  • 艾萨克·维尔舒普

  • JHM 达比郡

  • JHM 达比郡 (iMac)

  • 伯利

  • 海梅·迪·克里斯蒂娜

  • 简·科赫

  • JanVHII +

  • 贾诺什·里伯塞尔

  • 贾斯曼迪普·考尔 +

  • 杰里米·图鲁普

  • 杰西卡·M+

  • 乔纳斯·哈格

  • 乔里斯·范登博什

  • 若昂·梅雷莱斯 +

  • 朱莉娅·奥恩 +

  • 贾斯图斯·马金 +

  • 康素敏+

  • 凯文·谢泼德

  • 许增伟

  • 基安·埃利亚西

  • 克斯特亚·法伯 +

  • Kotlin岛 +

  • 拉克马尔·皮纳杜瓦格 +

  • 拉克夏·阿格拉瓦尔 +

  • 劳伦斯·米切尔 +

  • 列维奥布+

  • 卢伊克·迪里多卢

  • 洛伦佐·瓦尼利 +

  • 卢卡·皮齐尼 +

  • 卢卡斯·达莫 +

  • 卢克·曼利

  • 玛杜丽·帕蒂尔 +

  • 马克·加西亚

  • 马可·爱德华·戈雷利

  • 马可·戈雷利

  • 马可·戈雷利

  • 马伦·韦斯特曼 +

  • 玛丽亚·斯塔泽罗娃 +

  • 玛丽·K+

  • 玛丽埃尔+

  • 马克·哈富什 +

  • 马尔科·帕卡克 +

  • 马丁+

  • 马修斯·塞尔奎拉 +

  • 马修斯·佩德罗尼 +

  • 马泰奥·拉索 +

  • 马修·罗斯克

  • Meeseeks机器 +

  • 迈赫迪·穆罕默迪 +

  • 迈克尔·哈里斯 +

  • 迈克尔·米奥 +

  • 纳塔利娅·莫基耶娃 +

  • 尼尔·穆皮迪 +

  • 尼克·克鲁斯

  • 尼舒·乔杜里 +

  • 诺亚·塔米尔

  • 小林德忠

  • 奥姆卡尔·亚达夫 +

  • P·塔利 +

  • 巴勃罗+

  • 熊猫开发团队

  • 冻糕加萨娜

  • 帕特里克·赫夫勒

  • 佩德罗·纳赫特 +

  • 菲利普+

  • 彼得罗·巴蒂斯顿

  • 普贾·苏布拉马尼亚姆 +

  • 普拉纳夫·赛布山·拉乌里 +

  • 普拉纳夫。 P.A+

  • 拉尔夫·戈默斯 +

  • RaphSku +

  • 理查德·沙德拉赫

  • 罗布斯杜德 +

  • 罗杰

  • 罗杰·托马斯

  • 罗杰·托马斯 +

  • 富勒4 +

  • 萨拉赫丁+

  • 萨姆·拉奥

  • 肖恩·帕特里克·马洛伊 +

  • 塞巴斯蒂安·罗尔 +

  • 尚塔努

  • 沙什瓦特 +

  • 沙什瓦特·阿格拉瓦尔 +

  • 希科·万威亚 +

  • 肖汉姆·德布纳斯

  • 舒布汉卡尔·洛哈尼 +

  • 悉达多·甘地 +

  • 西蒙·霍金斯

  • 苏米克·杜塔 +

  • 索罗夫·塔鲁克德尔 +

  • 斯蒂芬妮·莫林

  • 斯蒂芬妮·森格 +

  • 斯蒂芬·肖恩 +

  • 史蒂文·罗通多

  • 斯蒂恩·范霍伊

  • 苏丹苏+

  • 斯文

  • 西尔万·玛丽

  • 西尔万·玛丽

  • 塔贝亚·科森 +

  • 泰勒·帕卡德

  • 特尔吉·彼得森

  • 蒂埃里·莫伊桑

  • 托马斯·H+

  • 托马斯·李

  • 托斯顿·沃特温

  • 茨维卡S+

  • 茨维卡·夏皮拉 +

  • 瓦姆西·维尔玛 +

  • 维尼修斯·阿基拉 +

  • 威廉·安德烈

  • 威廉·艾德

  • 威廉·布鲁姆 +

  • 邢+

  • 小袁+

  • X不是+

  • 亚辛·塔塔尔 +

  • 耿元浩

  • 伊万·赛万 +

  • 扎卡里·穆恩 +

  • 王正波+

  • 阿邦特+

  • 阿德里安太平洋 +

  • 施舍

  • 阿莫佐普+

  • 安迪耶森 +

  • 匿名鼠标1 +

  • 砰128 +

  • 比什瓦斯·杰哈 +

  • 卡霍克迈耶 +

  • 卡拉-阿尔维斯-24 +

  • 卡洛塔+

  • 卡萨迪皮特拉 +

  • 卡特玛22 +

  • cfabian +

  • 科达缪斯 +

  • 数据处理

  • 大卫利恩123 +

  • 依赖机器人[机器人] +

  • 夫德罗查+

  • github-actions[机器人]

  • 希曼舒_瓦格 +

  • iofall +

  • 贾克卡姆 +

  • 杰布罗克门德尔

  • jnclt+

  • 乔尔琴+

  • 乔尔索诺达 +

  • 约书亚贝洛2550

  • 乔伊斯瓦姆韦亚 +

  • 凯瑟琳杭 +

  • 克拉什+

  • 托尼亚齐 +

  • 卢克396 +

  • 米沃什·马丁诺夫 +

  • 米纳特枢纽 +

  • mliu08+

  • 莫桑烷+

  • 尼尔克斯姆

  • 尼基塔韦德 +

  • 悖论实验室 +

  • 帕尔捷夫

  • 赖萨兹 +

  • 拉姆·维克拉姆·辛格 +

  • 丽贝卡·帕尔默

  • 萨瓦桑杰 +

  • 塞尔雅克斯 +

  • 西尔维奥沃 +

  • smij720+

  • 苏米尔巴尔多塔 +

  • 星灵7 +

  • 草莓沙滩凉鞋+

  • 特莫舒 +

  • 乌塞尔 +

  • yqyqyq-W+

  • 云+

  • 阿达姆·利帕伊

  • 김동현 (Daniel Donghyun Kim) +