0.25.0 版本新增功能(2019 年 7 月 18 日)#

警告

从 0.25.x 系列版本开始,pandas 只支持 Python 3.5.3 及更高版本。有关详细信息,请参阅 弃用 Python 2.7

警告

在未来的版本中,最低支持的 Python 版本将提升至 3.6。

警告

Panel 已被完全移除。对于 N 维标签数据结构,请使用 xarray

警告

read_pickle()read_msgpack() 仅保证向后兼容至 pandas 0.20.3 版本 (GH 27082)。

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

改进#

GroupBy 聚合及重新标记#

pandas 新增了一种特殊的 groupby 行为,称为“命名聚合”,用于在对特定列应用多个聚合函数时命名输出列 (GH 18366, GH 26512)。

In [1]: animals = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
   ...:                         'height': [9.1, 6.0, 9.5, 34.0],
   ...:                         'weight': [7.9, 7.5, 9.9, 198.0]})
   ...: 

In [2]: animals
Out[2]: 
  kind  height  weight
0  cat     9.1     7.9
1  dog     6.0     7.5
2  cat     9.5     9.9
3  dog    34.0   198.0

[4 rows x 3 columns]

In [3]: animals.groupby("kind").agg(
   ...:     min_height=pd.NamedAgg(column='height', aggfunc='min'),
   ...:     max_height=pd.NamedAgg(column='height', aggfunc='max'),
   ...:     average_weight=pd.NamedAgg(column='weight', aggfunc="mean"),
   ...: )
   ...: 
Out[3]: 
      min_height  max_height  average_weight
kind                                        
cat          9.1         9.5            8.90
dog          6.0        34.0          102.75

[2 rows x 3 columns]

将期望的列名作为 **kwargs 参数传递给 .agg**kwargs 的值应为元组,其中第一个元素是列选择,第二个元素是要应用的聚合函数。 pandas 提供了 pandas.NamedAgg 命名元组,以使函数的参数更清晰,但也接受普通元组。

In [4]: animals.groupby("kind").agg(
   ...:     min_height=('height', 'min'),
   ...:     max_height=('height', 'max'),
   ...:     average_weight=('weight', 'mean'),
   ...: )
   ...: 
Out[4]: 
      min_height  max_height  average_weight
kind                                        
cat          9.1         9.5            8.90
dog          6.0        34.0          102.75

[2 rows x 3 columns]

命名聚合是弃用的“字典嵌套字典”方法(用于命名列特定聚合的输出)的推荐替代方案 (弃用使用字典重命名时 groupby.agg() 的用法)。

对于 Series 的 groupby 对象,现在也提供了类似的方法。由于不需要选择列,值可以直接是应用函数。

In [5]: animals.groupby("kind").height.agg(
   ...:     min_height="min",
   ...:     max_height="max",
   ...: )
   ...: 
Out[5]: 
      min_height  max_height
kind                        
cat          9.1         9.5
dog          6.0        34.0

[2 rows x 2 columns]

这种聚合类型是弃用行为的推荐替代方案,即当将字典传递给 Series 的 groupby 聚合时 (弃用使用字典重命名时 groupby.agg() 的用法)。

更多详细信息请参阅 命名聚合

GroupBy 聚合支持多个 lambda 函数#

现在可以在 GroupBy.agg 的列表式聚合中提供多个 lambda 函数 (GH 26430)。

In [6]: animals.groupby('kind').height.agg([
   ...:     lambda x: x.iloc[0], lambda x: x.iloc[-1]
   ...: ])
   ...: 
Out[6]: 
      <lambda_0>  <lambda_1>
kind                        
cat          9.1         9.5
dog          6.0        34.0

[2 rows x 2 columns]

In [7]: animals.groupby('kind').agg([
   ...:     lambda x: x.iloc[0] - x.iloc[1],
   ...:     lambda x: x.iloc[0] + x.iloc[1]
   ...: ])
   ...: 
Out[7]: 
         height                weight           
     <lambda_0> <lambda_1> <lambda_0> <lambda_1>
kind                                            
cat        -0.4       18.6       -2.0       17.8
dog       -28.0       40.0     -190.5      205.5

[2 rows x 4 columns]

之前,这会引发 SpecificationError

MultiIndex 更好的表示形式#

现在打印 MultiIndex 实例时会显示每行的元组,并确保元组项垂直对齐,因此现在更容易理解 MultiIndex 的结构。 (GH 13480)

现在表示形式如下所示

In [8]: pd.MultiIndex.from_product([['a', 'abc'], range(500)])
Out[8]: 
MultiIndex([(  'a',   0),
            (  'a',   1),
            (  'a',   2),
            (  'a',   3),
            (  'a',   4),
            (  'a',   5),
            (  'a',   6),
            (  'a',   7),
            (  'a',   8),
            (  'a',   9),
            ...
            ('abc', 490),
            ('abc', 491),
            ('abc', 492),
            ('abc', 493),
            ('abc', 494),
            ('abc', 495),
            ('abc', 496),
            ('abc', 497),
            ('abc', 498),
            ('abc', 499)],
           length=1000)

以前,输出 MultiIndex 会打印 MultiIndex 的所有 levelscodes,这在视觉上不够美观,且使输出更难以浏览。例如(范围限制为 5)

In [1]: pd.MultiIndex.from_product([['a', 'abc'], range(5)])
Out[1]: MultiIndex(levels=[['a', 'abc'], [0, 1, 2, 3]],
   ...:            codes=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 1, 2, 3, 0, 1, 2, 3]])

在新的表示形式中,如果行数少于 options.display.max_seq_items(默认:100 项),则会显示所有值。水平方向上,如果宽度超过 options.display.width(默认:80 个字符),则输出将被截断。

Series 和 DataFrame 更短的截断表示形式#

目前,pandas 的默认显示选项确保当 Series 或 DataFrame 的行数超过 60 行时,其表示形式会截断到最大 60 行(display.max_rows 选项)。然而,这仍然使得表示形式占据了垂直屏幕的大部分空间。因此,引入了一个新的选项 display.min_rows,默认值为 10,它决定了截断表示形式中显示的行数。

  • 对于小型 Series 或 DataFrame,最多显示 max_rows 行(默认:60)。

  • 对于长度超过 max_rows 的大型 Series 或 DataFrame,仅显示 min_rows 行(默认:10,即前 5 行和后 5 行)。

这个双重选项允许仍然查看相对较小对象的完整内容(例如 df.head(20) 显示所有 20 行),同时为大型对象提供简洁的表示形式。

要恢复以前的单一阈值行为,请设置 pd.options.display.min_rows = None

JSON 规范化支持 max_level 参数#

json_normalize() 会将提供的输入字典规范化到所有嵌套级别。新的 max_level 参数提供了对在哪个级别结束规范化进行更精细的控制 (GH 23843)。

现在表示形式如下所示

from pandas.io.json import json_normalize
data = [{
    'CreatedBy': {'Name': 'User001'},
    'Lookup': {'TextField': 'Some text',
               'UserField': {'Id': 'ID001', 'Name': 'Name001'}},
    'Image': {'a': 'b'}
}]
json_normalize(data, max_level=1)

Series.explode 将列表状值拆分成行#

SeriesDataFrame 增加了 DataFrame.explode() 方法,用于将列表状值转换为单独的行。更多信息请参阅文档中的 展开列表状列的章节 (GH 16538, GH 10511)。

这是一个典型的用例。你有一个包含逗号分隔字符串的列。

In [9]: df = pd.DataFrame([{'var1': 'a,b,c', 'var2': 1},
   ...:                    {'var1': 'd,e,f', 'var2': 2}])
   ...: 

In [10]: df
Out[10]: 
    var1  var2
0  a,b,c     1
1  d,e,f     2

[2 rows x 2 columns]

现在可以使用链式操作轻松创建长格式的 DataFrame

In [11]: df.assign(var1=df.var1.str.split(',')).explode('var1')
Out[11]: 
  var1  var2
0    a     1
0    b     1
0    c     1
1    d     2
1    e     2
1    f     2

[6 rows x 2 columns]

其他改进#

向后不兼容的 API 更改#

使用带有时区偏移的日期字符串进行索引#

以前,使用带有时区偏移的日期字符串对具有 DatetimeIndexDataFrameSeries 进行索引时会忽略时区偏移。现在,索引时会考虑时区偏移。 (GH 24076, GH 16785)

In [12]: df = pd.DataFrame([0], index=pd.DatetimeIndex(['2019-01-01'], tz='US/Pacific'))

In [13]: df
Out[13]: 
                           0
2019-01-01 00:00:00-08:00  0

[1 rows x 1 columns]

以前的行为:

In [3]: df['2019-01-01 00:00:00+04:00':'2019-01-01 01:00:00+04:00']
Out[3]:
                           0
2019-01-01 00:00:00-08:00  0

新的行为:

In [14]: df['2019-01-01 12:00:00+04:00':'2019-01-01 13:00:00+04:00']
Out[14]: 
                           0
2019-01-01 00:00:00-08:00  0

[1 rows x 1 columns]

由 levels 和 codes 构造的 MultiIndex#

以前允许使用 NaN levels 或 codes 值 < -1 来构造 MultiIndex。现在,不允许使用 codes 值 < -1 进行构造,并且 NaN levels 对应的 codes 将被重新赋值为 -1。 (GH 19387)

以前的行为:

In [1]: pd.MultiIndex(levels=[[np.nan, None, pd.NaT, 128, 2]],
   ...:               codes=[[0, -1, 1, 2, 3, 4]])
   ...:
Out[1]: MultiIndex(levels=[[nan, None, NaT, 128, 2]],
                   codes=[[0, -1, 1, 2, 3, 4]])

In [2]: pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
Out[2]: MultiIndex(levels=[[1, 2]],
                   codes=[[0, -2]])

新的行为:

In [15]: pd.MultiIndex(levels=[[np.nan, None, pd.NaT, 128, 2]],
   ....:               codes=[[0, -1, 1, 2, 3, 4]])
   ....: 
Out[15]: 
MultiIndex([(nan,),
            (nan,),
            (nan,),
            (nan,),
            (128,),
            (  2,)],
           )

In [16]: pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[16], line 1
----> 1 pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])

File ~/work/pandas/pandas/pandas/core/indexes/multi.py:364, in MultiIndex.__new__(cls, levels, codes, sortorder, names, dtype, copy, name, verify_integrity)
    361     result.sortorder = sortorder
    363 if verify_integrity:
--> 364     new_codes = result._verify_integrity()
    365     result._codes = new_codes
    367 result._reset_identity()

File ~/work/pandas/pandas/pandas/core/indexes/multi.py:451, in MultiIndex._verify_integrity(self, codes, levels, levels_to_verify)
    445     raise ValueError(
    446         f"On level {i}, code max ({level_codes.max()}) >= length of "
    447         f"level ({len(level)}). NOTE: this index is in an "
    448         "inconsistent state"
    449     )
    450 if len(level_codes) and level_codes.min() < -1:
--> 451     raise ValueError(f"On level {i}, code value ({level_codes.min()}) < -1")
    452 if not level.is_unique:
    453     raise ValueError(
    454         f"Level values must be unique: {list(level)} on level {i}"
    455     )

ValueError: On level 0, code value (-2) < -1

DataFrame 上执行 GroupBy.apply 只评估第一个组一次#

以前 DataFrameGroupBy.apply() 的实现会对第一个组一致地评估两次提供的函数,以推断是否可以安全地使用快速代码路径。特别是对于具有副作用的函数,这是一个不需要的行为,并可能导致意外。 (GH 2936, GH 2656, GH 7739, GH 10519, GH 12155, GH 20084, GH 21417)

现在每个组只评估一次。

In [17]: df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})

In [18]: df
Out[18]: 
   a  b
0  x  1
1  y  2

[2 rows x 2 columns]

In [19]: def func(group):
   ....:     print(group.name)
   ....:     return group
   ....: 

以前的行为:

In [3]: df.groupby('a').apply(func)
x
x
y
Out[3]:
   a  b
0  x  1
1  y  2

新的行为:

In [3]: df.groupby('a').apply(func)
x
y
Out[3]:
   a  b
0  x  1
1  y  2

连接稀疏值#

当传递值为稀疏的 DataFrames 时,concat() 现在将返回带有稀疏值的 SeriesDataFrame,而不是 SparseDataFrame (GH 25702)。

In [20]: df = pd.DataFrame({"A": pd.arrays.SparseArray([0, 1])})

以前的行为:

In [2]: type(pd.concat([df, df]))
pandas.core.sparse.frame.SparseDataFrame

新的行为:

In [21]: type(pd.concat([df, df]))
Out[21]: pandas.core.frame.DataFrame

这与现有的对带有稀疏值的 Series 执行 concat 的行为一致。当所有值都是 SparseDataFrame 的实例时,concat() 将继续返回 SparseDataFrame

此更改也影响了内部使用 concat() 的例程,例如 get_dummies(),它现在在所有情况下都返回 DataFrame(以前,如果所有列都进行了独热编码,则返回 SparseDataFrame,否则返回 DataFrame)。

将任何 SparseSeriesSparseDataFrame 提供给 concat() 将导致返回 SparseSeriesSparseDataFrame,与以前一样。

.str 访问器执行更严格的类型检查#

由于缺少更细粒度的 dtype,Series.str 迄今为止只检查数据是否为 object dtype。现在,Series.str 将推断 Series 内部的数据 dtype;特别是,纯 'bytes' 数据将引发异常(Series.str.decode()Series.str.get()Series.str.len()Series.str.slice() 除外),详情请参见 GH 23163GH 23011GH 23551

以前的行为:

In [1]: s = pd.Series(np.array(['a', 'ba', 'cba'], 'S'), dtype=object)

In [2]: s
Out[2]:
0      b'a'
1     b'ba'
2    b'cba'
dtype: object

In [3]: s.str.startswith(b'a')
Out[3]:
0     True
1    False
2    False
dtype: bool

新的行为:

In [22]: s = pd.Series(np.array(['a', 'ba', 'cba'], 'S'), dtype=object)

In [23]: s
Out[23]: 
0      b'a'
1     b'ba'
2    b'cba'
Length: 3, dtype: object

In [24]: s.str.startswith(b'a')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[24], line 1
----> 1 s.str.startswith(b'a')

File ~/work/pandas/pandas/pandas/core/strings/accessor.py:136, in forbid_nonstring_types.<locals>._forbid_nonstring_types.<locals>.wrapper(self, *args, **kwargs)
    131 if self._inferred_dtype not in allowed_types:
    132     msg = (
    133         f"Cannot use .str.{func_name} with values of "
    134         f"inferred dtype '{self._inferred_dtype}'."
    135     )
--> 136     raise TypeError(msg)
    137 return func(self, *args, **kwargs)

TypeError: Cannot use .str.startswith with values of inferred dtype 'bytes'.

Categorical dtypes 在 GroupBy 期间被保留#

此前,在 groupby 操作期间,属于分类但不是 groupby 键的列会被转换为 object dtype。pandas 现在会保留这些 dtypes。(GH 18502

In [25]: cat = pd.Categorical(["foo", "bar", "bar", "qux"], ordered=True)

In [26]: df = pd.DataFrame({'payload': [-1, -2, -1, -2], 'col': cat})

In [27]: df
Out[27]: 
   payload  col
0       -1  foo
1       -2  bar
2       -1  bar
3       -2  qux

[4 rows x 2 columns]

In [28]: df.dtypes
Out[28]: 
payload       int64
col        category
Length: 2, dtype: object

以前的行为:

In [5]: df.groupby('payload').first().col.dtype
Out[5]: dtype('O')

新行为:

In [29]: df.groupby('payload').first().col.dtype
Out[29]: CategoricalDtype(categories=['bar', 'foo', 'qux'], ordered=True, categories_dtype=object)

不兼容的 Index 类型合并#

在对不兼容 dtype 的对象执行 Index.union() 操作时,结果将是 dtype 为 object 的基础 Index。对于之前被禁止的 Index 对象之间的合并,此行为也成立。空的 Index 对象的 dtype 现在将在执行合并操作之前进行评估,而不是简单地返回另一个 Index 对象。Index.union() 现在可以视为可交换的,即 A.union(B) == B.union(A)GH 23525)。

以前的行为:

In [1]: pd.period_range('19910905', periods=2).union(pd.Int64Index([1, 2, 3]))
...
ValueError: can only call with other PeriodIndex-ed objects

In [2]: pd.Index([], dtype=object).union(pd.Index([1, 2, 3]))
Out[2]: Int64Index([1, 2, 3], dtype='int64')

新的行为:

In [3]: pd.period_range('19910905', periods=2).union(pd.Int64Index([1, 2, 3]))
Out[3]: Index([1991-09-05, 1991-09-06, 1, 2, 3], dtype='object')
In [4]: pd.Index([], dtype=object).union(pd.Index([1, 2, 3]))
Out[4]: Index([1, 2, 3], dtype='object')

请注意,整数和浮点 dtype 的索引被认为是“兼容的”。整数值会被强制转换为浮点类型,这可能会导致精度损失。更多信息请参见 Index 对象上的集合操作

DataFrame GroupBy ffill/bfill 不再返回组标签#

DataFrameGroupBy 的方法 ffillbfillpadbackfill 以前在返回值中包含组标签,这与其他 groupby 转换不一致。现在只返回填充后的值。(GH 21521

In [30]: df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})

In [31]: df
Out[31]: 
   a  b
0  x  1
1  y  2

[2 rows x 2 columns]

以前的行为:

In [3]: df.groupby("a").ffill()
Out[3]:
   a  b
0  x  1
1  y  2

新的行为:

In [32]: df.groupby("a").ffill()
Out[32]: 
   b
0  1
1  2

[2 rows x 1 columns]

DataFrame 对空的 Categorical / object 列执行 describe 将返回 top 和 freq#

对空的 categorical / object 列调用 DataFrame.describe() 时,以前会省略 'top' 和 'freq' 列,这与非空列的输出不一致。现在,'top' 和 'freq' 列将始终包含在内,对于空的 DataFrame,它们的值为 numpy.nan。(GH 26397

In [33]: df = pd.DataFrame({"empty_col": pd.Categorical([])})

In [34]: df
Out[34]: 
Empty DataFrame
Columns: [empty_col]
Index: []

[0 rows x 1 columns]

以前的行为:

In [3]: df.describe()
Out[3]:
        empty_col
count           0
unique          0

新的行为:

In [35]: df.describe()
Out[35]: 
       empty_col
count          0
unique         0
top          NaN
freq         NaN

[4 rows x 1 columns]

__str__ 方法现在调用 __repr__,而不是反过来#

到目前为止,pandas 主要在其对象的 __str__/__unicode__/__bytes__ 方法中定义字符串表示,并且如果在未找到特定的 __repr__ 方法时,从 __repr__ 方法中调用 __str__。这在 Python3 中是不需要的。在 pandas 0.25 中,pandas 对象的字符串表示现在通常在 __repr__ 中定义,并且如果不存在特定的 __str__ 方法,则通常对 __str__ 的调用会传递给 __repr__,这与 Python 标准一致。对于直接使用 pandas 而言,此更改是向后兼容的,但如果您继承 pandas 对象*并且*为您的子类提供特定的 __str__/__repr__ 方法,则可能需要调整您的 __str__/__repr__ 方法(GH 26495)。

使用 Interval 对象索引 IntervalIndex#

IntervalIndex 的索引方法已被修改为仅对 Interval 查询要求精确匹配。以前的 IntervalIndex 方法会匹配任何重叠的 Interval。使用标量点(例如,使用整数查询)的行为不变(GH 16316)。

In [36]: ii = pd.IntervalIndex.from_tuples([(0, 4), (1, 5), (5, 8)])

In [37]: ii
Out[37]: IntervalIndex([(0, 4], (1, 5], (5, 8]], dtype='interval[int64, right]')

in 运算符 (__contains__) 现在仅对 IntervalIndexIntervals 的精确匹配返回 True,而以前对于任何与 IntervalIndex 中某个 Interval 重叠的 Interval 都会返回 True

以前的行为:

In [4]: pd.Interval(1, 2, closed='neither') in ii
Out[4]: True

In [5]: pd.Interval(-10, 10, closed='both') in ii
Out[5]: True

新的行为:

In [38]: pd.Interval(1, 2, closed='neither') in ii
Out[38]: False

In [39]: pd.Interval(-10, 10, closed='both') in ii
Out[39]: False

get_loc() 方法现在仅返回 Interval 查询的精确匹配位置,而以前的行为是返回重叠匹配的位置。如果找不到精确匹配,将引发 KeyError

以前的行为:

In [6]: ii.get_loc(pd.Interval(1, 5))
Out[6]: array([0, 1])

In [7]: ii.get_loc(pd.Interval(2, 6))
Out[7]: array([0, 1, 2])

新的行为:

In [6]: ii.get_loc(pd.Interval(1, 5))
Out[6]: 1

In [7]: ii.get_loc(pd.Interval(2, 6))
---------------------------------------------------------------------------
KeyError: Interval(2, 6, closed='right')

同样,get_indexer()get_indexer_non_unique() 也将仅返回 Interval 查询的精确匹配位置,其中 -1 表示未找到精确匹配。

这些索引更改也适用于使用 IntervalIndex 索引查询 SeriesDataFrame

In [40]: s = pd.Series(list('abc'), index=ii)

In [41]: s
Out[41]: 
(0, 4]    a
(1, 5]    b
(5, 8]    c
Length: 3, dtype: object

使用 [] (__getitem__) 或 locSeriesDataFrame 中选择时,现在仅返回 Interval 查询的精确匹配。

以前的行为:

In [8]: s[pd.Interval(1, 5)]
Out[8]:
(0, 4]    a
(1, 5]    b
dtype: object

In [9]: s.loc[pd.Interval(1, 5)]
Out[9]:
(0, 4]    a
(1, 5]    b
dtype: object

新的行为:

In [42]: s[pd.Interval(1, 5)]
Out[42]: 'b'

In [43]: s.loc[pd.Interval(1, 5)]
Out[43]: 'b'

类似地,对于非精确匹配,将引发 KeyError,而不是返回重叠匹配。

以前的行为:

In [9]: s[pd.Interval(2, 3)]
Out[9]:
(0, 4]    a
(1, 5]    b
dtype: object

In [10]: s.loc[pd.Interval(2, 3)]
Out[10]:
(0, 4]    a
(1, 5]    b
dtype: object

新的行为:

In [6]: s[pd.Interval(2, 3)]
---------------------------------------------------------------------------
KeyError: Interval(2, 3, closed='right')

In [7]: s.loc[pd.Interval(2, 3)]
---------------------------------------------------------------------------
KeyError: Interval(2, 3, closed='right')

可以使用 overlaps() 方法创建一个布尔索引器,以复制以前返回重叠匹配的行为。

新的行为:

In [44]: idxr = s.index.overlaps(pd.Interval(2, 3))

In [45]: idxr
Out[45]: array([ True,  True, False])

In [46]: s[idxr]
Out[46]: 
(0, 4]    a
(1, 5]    b
Length: 2, dtype: object

In [47]: s.loc[idxr]
Out[47]: 
(0, 4]    a
(1, 5]    b
Length: 2, dtype: object

Series 上的二元 ufunc 现在进行对齐#

当两个输入都是 Series 时,应用像 numpy.power() 这样的二元 ufunc 现在会对其输入进行对齐(GH 23293)。

In [48]: s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

In [49]: s2 = pd.Series([3, 4, 5], index=['d', 'c', 'b'])

In [50]: s1
Out[50]: 
a    1
b    2
c    3
Length: 3, dtype: int64

In [51]: s2
Out[51]: 
d    3
c    4
b    5
Length: 3, dtype: int64

以前的行为

In [5]: np.power(s1, s2)
Out[5]:
a      1
b     16
c    243
dtype: int64

新的行为

In [52]: np.power(s1, s2)
Out[52]: 
a     1.0
b    32.0
c    81.0
d     NaN
Length: 4, dtype: float64

这与其他 pandas 二元操作(如 Series.add())的行为一致。要保留以前的行为,请在应用 ufunc 之前将另一个 Series 转换为数组。

In [53]: np.power(s1, s2.array)
Out[53]: 
a      1
b     16
c    243
Length: 3, dtype: int64

Categorical.argsort 现在将缺失值放在末尾#

Categorical.argsort() 现在将缺失值放在数组的末尾,使其与 NumPy 和 pandas 的其余部分保持一致(GH 21801)。

In [54]: cat = pd.Categorical(['b', None, 'a'], categories=['a', 'b'], ordered=True)

以前的行为

In [2]: cat = pd.Categorical(['b', None, 'a'], categories=['a', 'b'], ordered=True)

In [3]: cat.argsort()
Out[3]: array([1, 2, 0])

In [4]: cat[cat.argsort()]
Out[4]:
[NaN, a, b]
categories (2, object): [a < b]

新的行为

In [55]: cat.argsort()
Out[55]: array([2, 0, 1])

In [56]: cat[cat.argsort()]
Out[56]: 
['a', 'b', NaN]
Categories (2, object): ['a' < 'b']

将字典列表传递给 DataFrame 时会保留列顺序#

从 Python 3.7 开始,dict 的键顺序是保证的。实际上,从 Python 3.6 开始就是如此。DataFrame 构造函数现在以与处理 OrderedDict 列表相同的方式处理字典列表,即保留字典的顺序。此更改仅在 pandas 运行于 Python>=3.6 时适用(GH 27309)。

In [57]: data = [
   ....:     {'name': 'Joe', 'state': 'NY', 'age': 18},
   ....:     {'name': 'Jane', 'state': 'KY', 'age': 19, 'hobby': 'Minecraft'},
   ....:     {'name': 'Jean', 'state': 'OK', 'age': 20, 'finances': 'good'}
   ....: ]
   ....: 

以前的行为:

以前,列按字典顺序排序,

In [1]: pd.DataFrame(data)
Out[1]:
   age finances      hobby  name state
0   18      NaN        NaN   Joe    NY
1   19      NaN  Minecraft  Jane    KY
2   20     good        NaN  Jean    OK

新行为:

现在的列顺序匹配字典中键的插入顺序,从上到下考虑所有记录。因此,与以前的 pandas 版本相比,结果 DataFrame 的列顺序已发生变化。

In [58]: pd.DataFrame(data)
Out[58]: 
   name state  age      hobby finances
0   Joe    NY   18        NaN      NaN
1  Jane    KY   19  Minecraft      NaN
2  Jean    OK   20        NaN     good

[3 rows x 5 columns]

增加依赖项的最低版本要求#

由于放弃了对 Python 2.7 的支持,一些可选依赖项的最低版本要求已更新(GH 25725GH 24942GH 25752)。此外,一些依赖项的最低支持版本也已更新(GH 23519GH 25554)。如果已安装,现在需要

最低版本

必需

numpy

1.13.3

X

pytz

2015.4

X

python-dateutil

2.6.1

X

bottleneck

1.2.1

numexpr

2.6.2

pytest (dev)

4.0.2

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

最低版本

beautifulsoup4

4.6.0

fastparquet

0.2.1

gcsfs

0.2.2

lxml

3.8.0

matplotlib

2.2.2

openpyxl

2.4.8

pyarrow

0.9.0

pymysql

0.7.1

pytables

3.4.2

scipy

0.19.0

sqlalchemy

1.1.4

xarray

0.8.2

xlrd

1.1.0

xlsxwriter

0.9.8

xlwt

1.2.0

更多信息请参见依赖项可选依赖项

其他 API 更改#

弃用#

Sparse 子类#

SparseSeriesSparseDataFrame 子类已被弃用。它们的功用现在通过带有稀疏值的 SeriesDataFrame 更好地提供。

以前的方式

df = pd.SparseDataFrame({"A": [0, 0, 1, 2]})
df.dtypes

新的方式

In [59]: df = pd.DataFrame({"A": pd.arrays.SparseArray([0, 0, 1, 2])})

In [60]: df.dtypes
Out[60]: 
A    Sparse[int64, 0]
Length: 1, dtype: object

这两种方法的内存使用是相同的(GH 19239)。

msgpack 格式#

msgpack 格式自 0.25 版本起已被弃用,并将在未来版本中移除。建议使用 pyarrow 进行 pandas 对象的在线传输。(GH 27084

其他弃用#

移除先前版本弃用/变更的功能#

  • 移除了 Panel。(GH 25047, GH 25191, GH 25231)

  • 移除了先前在 read_excel() 中已弃用的 sheetname 关键字。(GH 16442, GH 20938)

  • 移除了先前已弃用的 TimeGrouper。(GH 16942)

  • 移除了先前在 read_excel() 中已弃用的 parse_cols 关键字。(GH 16488)

  • 移除了先前已弃用的 pd.options.html.border。(GH 16970)

  • 移除了先前已弃用的 convert_objects。(GH 11221)

  • 移除了先前在 DataFrameSeries 中已弃用的 select 方法。(GH 17633)

  • 移除了先前在 rename_categories() 中将 Series 视为列表的已弃用行为。(GH 17982)

  • 移除了先前已弃用的 DataFrame.reindex_axisSeries.reindex_axis。(GH 17842)

  • 移除了先前在使用 Series.rename_axis()DataFrame.rename_axis() 修改列或索引标签的已弃用行为。(GH 17842)

  • 移除了先前在 read_html()read_csv()DataFrame.to_csv() 中已弃用的 tupleize_cols 关键字参数。(GH 17877, GH 17820)

  • 移除了先前已弃用的 DataFrame.from.csvSeries.from_csv。(GH 17812)

  • 移除了先前在 DataFrame.where()DataFrame.mask() 中已弃用的 raise_on_error 关键字参数。(GH 17744)

  • 移除了先前在 astype 中已弃用的 orderedcategories 关键字参数。(GH 17742)

  • 移除了先前已弃用的 cdate_range。(GH 17691)

  • 移除了先前在 SeriesGroupBy.nth() 中为 dropna 关键字参数设置 True 选项的已弃用功能。(GH 17493)

  • 移除了先前在 Series.take()DataFrame.take() 中已弃用的 convert 关键字参数。(GH 17352)

  • 移除了先前已弃用的与 datetime.date 对象执行算术运算的行为。(GH 21152)

性能改进#

  • 显著提高了 SparseArray 初始化速度,这有益于大多数操作,修复了 v0.20.0 中引入的性能回归。(GH 24985)

  • DataFrame.to_stata() 现在输出包含字符串或非本地字节序列的数据时速度更快。(GH 25045)

  • 改进了 Series.searchsorted() 的性能。当 dtype 为 int8/int16/int32 且搜索的键在 dtype 的整数范围内时,速度提升尤其明显。(GH 22034)

  • 改进了 GroupBy.quantile() 的性能。(GH 20405)

  • 改进了 RangeIndex 切片和其他选定操作的性能。(GH 26565, GH 26617, GH 26722)

  • RangeIndex 现在执行标准查找时不再实例化实际的哈希表,从而节省了内存。(GH 16685)

  • 改进了 read_csv() 的性能,通过更快的词法分析和小浮点数解析实现。(GH 25784)

  • 改进了 read_csv() 的性能,通过更快地解析 N/A 和布尔值实现。(GH 25804)

  • 通过移除到 MultiIndex 的转换,改进了 IntervalIndex.is_monotonicIntervalIndex.is_monotonic_increasingIntervalIndex.is_monotonic_decreasing 的性能。(GH 24813)

  • 改进了 DataFrame.to_csv() 写入 datetime dtypes 时的性能。(GH 25708)

  • 改进了 read_csv() 的性能,通过更快地解析 MM/YYYYDD/MM/YYYY 日期时间格式实现。(GH 25922)

  • 改进了不能存储 NaN 的 dtypes 的 nanops 性能。对于 Series.all()Series.any(),速度提升尤为显著。(GH 25070)

  • 改进了 Series.map() 对于分类 Series 上字典映射器的性能,通过映射分类而不是映射所有值来实现。(GH 23785)

  • 改进了 IntervalIndex.intersection() 的性能。(GH 24813)

  • 改进了 read_csv() 的性能,通过更快地连接日期列,对整数/浮点零和浮点 NaN 无需额外转换为字符串;通过更快地检查字符串是否可能是日期实现。(GH 25754)

  • 通过移除到 MultiIndex 的转换,改进了 IntervalIndex.is_unique 的性能。(GH 24813)

  • 通过重新启用专门的代码路径,恢复了 DatetimeIndex.__iter__() 的性能。(GH 26702)

  • 改进了构建至少包含一个 CategoricalIndex 层级的 MultiIndex 时的性能。(GH 22044)

  • 通过移除检查 SettingWithCopyWarning 时对垃圾回收的需求,改进了性能。(GH 27031)

  • 对于 to_datetime(),将 cache 参数的默认值更改为 True。(GH 26043)

  • 在给定非唯一、单调数据的情况下,改进了 DatetimeIndexPeriodIndex 切片的性能。(GH 27136)。

  • 改进了 pd.read_json() 处理面向索引数据的性能。(GH 26773)。

  • 改进了 MultiIndex.shape() 的性能。(GH 27384)。

Bug 修复#

分类类型 (Categorical)#

日期时间类 (Datetimelike)#

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在使用遥远的未来日期且指定 format 参数时,会引发 (不正确的) ValueError 而非 OutOfBoundsDatetime。(GH 23830)

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在使用 cache=Truearg 包含集合 {None, numpy.nan, pandas.NaT} 中至少两个不同元素时,会引发 InvalidIndexError: Reindexing only valid with uniquely valued Index objects。(GH 22305)

  • 修复了 DataFrameSeries 的一个 Bug,该 Bug 导致带有 dtype='datetime64[ns] 的时区感知数据未能转换为时区 naive (无时区) 数据。(GH 25843)

  • 改进了各种日期时间函数中的 Timestamp 类型检查,以防止在使用 datetime 子类时引发异常。(GH 25851)

  • 修复了 SeriesDataFrame repr 中的一个 Bug,该 Bug 导致 dtype=objectnp.datetime64('NaT')np.timedelta64('NaT') 被表示为 NaN。(GH 25445)

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在 error 设置为 coerce 时未能将无效参数替换为 NaT。(GH 26122)

  • 修复了将带有非零月份的 DateOffset 添加到 DatetimeIndex 时会引发 ValueError 的 Bug。(GH 26258)

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在使用无效日期和 NaN 值混合,且 format='%Y%m%d'error='coerce' 时,会引发未处理的 OverflowError。(GH 25512)

  • 修复了 isin() 用于日期时间类索引 (DatetimeIndex, TimedeltaIndex, PeriodIndex) 时忽略 levels 参数的 Bug。(GH 26675)

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在使用 format='%Y%m%d' 且对长度 >= 6 位数的无效整数日期调用,且设置 errors='ignore' 时,会引发 TypeError

  • 修复了将 PeriodIndex 与零维 numpy 数组进行比较时的 Bug。(GH 26689)

  • 修复了从使用非 ns 单位和超出范围时间戳的 numpy datetime64 数组构建 SeriesDataFrame 时生成错误数据的 Bug,现在将正确地引发 OutOfBoundsDatetime 错误。(GH 26206)。

  • 修复了 date_range() 的一个 Bug,该 Bug 在处理非常大或非常小的日期时会引发不必要的 OverflowError。(GH 26651)

  • 修复了将 Timestamp 添加到 np.timedelta64 对象时会引发异常而不是返回 Timestamp 的 Bug。(GH 24775)

  • 修复了将包含 np.datetime64 对象的零维 numpy 数组与 Timestamp 进行比较时错误地引发 TypeError 的 Bug。(GH 26916)

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在使用 cache=Truearg 包含不同时区偏移的日期时间字符串时,会引发 ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=True。(GH 26097)

时间差类型 (Timedelta)#

  • 修复了 TimedeltaIndex.intersection() 的一个 Bug,该 Bug 在处理非单调索引时,有时会返回空的 Index,但实际上存在交集。(GH 25913)

  • 修复了 TimedeltaNaT 之间比较时会引发 TypeError 的 Bug。(GH 26039)

  • 修复了将 BusinessHour 添加或减去到 Timestamp 时,导致结果时间分别落入下一天或前一天的 Bug。(GH 26381)

  • 修复了将 TimedeltaIndex 与零维 numpy 数组进行比较时的 Bug。(GH 26689)

时区 (Timezones)#

  • 修复了 DatetimeIndex.to_frame() 的一个 Bug,该 Bug 会将时区感知数据转换为时区 naive (无时区) 数据。(GH 25809)

  • 修复了 to_datetime() 在使用 utc=True 和日期时间字符串时,会将先前解析的 UTC 偏移应用于后续参数的 Bug。(GH 24992)

  • 修复了 Timestamp.tz_localize()Timestamp.tz_convert() 未能传播 freq 的 Bug。(GH 25241)

  • 修复了 Series.at() 在设置带有有时区信息的 Timestamp 时会引发 TypeError 的 Bug。(GH 25506)

  • 修复了 DataFrame.update() 在使用时区感知数据更新时会返回时区 naive (无时区) 数据的 Bug。(GH 25807)

  • 修复了 to_datetime() 的一个 Bug,该 Bug 在传入时区 naive 的 Timestamp 和带有混合 UTC 偏移的日期时间字符串时,会引发无信息的 RuntimeError。(GH 25978)

  • 修复了 to_datetime() 在使用 unit='ns' 时会丢弃解析参数中的时区信息的 Bug。(GH 26168)

  • 修复了 DataFrame.join() 的一个 Bug,该 Bug 在连接时区感知索引和时区感知列时,会导致结果列全是 NaN。(GH 26335)

  • 修复了 date_range() 的一个 Bug,该 Bug 未能分别使用 ambiguousnonexistent 关键字处理模糊或不存在的开始或结束时间。(GH 27088)

  • 修复了 DatetimeIndex.union() 在组合时区感知和时区 naive (无时区) 的 DatetimeIndex 时的 Bug。(GH 21671)

  • 应用 numpy 降维函数(例如 numpy.minimum())到时区感知的 Series 时出现的 Bug (GH 15552)

数值#

  • to_numeric() 中一个 Bug,涉及大型负数处理不当 (GH 24910)

  • to_numeric() 中一个 Bug,即便 errors 参数不是 coerce,数字也被强制转换为 float (GH 24910)

  • to_numeric() 中一个 Bug,errors 参数允许无效值 (GH 26466)

  • format 中一个 Bug,浮点复数没有以正确的显示精度和截断格式化 (GH 25514)

  • DataFrame.corr()Series.corr() 中错误消息的一个 Bug。增加了使用可调用对象的可能性。(GH 25729)

  • Series.divmod()Series.rdivmod() 中一个 Bug,错误地引发了 ValueError,而不是返回一对 Series 对象作为结果 (GH 25557)

  • 当使用需要数值索引的方法将非数值索引传递给 interpolate() 时,会引发更友好的异常。(GH 21662)

  • eval() 中一个 Bug,涉及使用标量运算符比较浮点数,例如:x < -0.1 (GH 25928)

  • 修复了一个 Bug,即将全布尔数组转换为整数扩展数组时失败 (GH 25211)

  • divmod 处理包含零的 Series 对象时一个 Bug,错误地引发了 AttributeError (GH 26987)

  • Series 整除 (//) 和 divmod 的不一致问题,将正数//零填充为 NaN 而不是 Inf (GH 27321)

转换#

字符串#

区间#

索引#

缺失值#

MultiIndex#

IO#

  • DataFrame.to_html() 中一个 Bug,值被显示选项截断,而不是输出完整内容 (GH 17004)

  • 修复了在 Windows 的 Python 3 中复制 utf-16 字符时,使用 to_clipboard() 出现文本缺失的 Bug (GH 25040)

  • read_json() 中当 orient='table' 且默认尝试推断 dtypes 时出现的 Bug,这不适用,因为 dtypes 已在 JSON schema 中定义 (GH 21345)

  • read_json() 中当 orient='table' 和 float 索引时出现的 Bug,它默认推断索引 dtype,这不适用,因为索引 dtype 已在 JSON schema 中定义 (GH 25433)

  • read_json() 中当 orient='table' 和 float 字符串列名时出现的 Bug,它将列名类型转换为 Timestamp,这不适用,因为列名已在 JSON schema 中定义 (GH 25435)

  • json_normalize() 中当 errors='ignore' 时出现的 Bug,输入数据中的缺失值在结果 DataFrame 中被字符串 "nan" 填充,而不是 numpy.nan (GH 25468)

  • DataFrame.to_html() 现在在使用 classes 参数的无效类型时会引发 TypeError,而不是 AssertionError (GH 25608)

  • DataFrame.to_string()DataFrame.to_latex() 中一个 Bug,在使用 header 关键字时会导致输出不正确 (GH 16718)

  • read_csv() 中一个 Bug,在 Windows 上的 Python 3.6+ 版本中无法正确解析 UTF8 编码的文件名 (GH 15086)

  • 改进了 pandas.read_stata()pandas.io.stata.StataReader 在转换包含缺失值的列时的性能 (GH 25772)

  • DataFrame.to_html() 中一个 Bug,标题数字在四舍五入时会忽略显示选项 (GH 17280)

  • read_hdf() 中一个 Bug,当使用 startstop 参数进行子选择时,从直接用 PyTables 写入的 HDF5 文件读取表格会因 ValueError 而失败 (GH 11188)

  • read_hdf() 中一个 Bug,在引发 KeyError 后未正确关闭存储 (GH 25766)

  • 改进了 Stata dta 文件中值标签重复时失败的解释,并提出了建议的解决方法 (GH 25772)

  • 改进了 pandas.read_stata()pandas.io.stata.StataReader 以读取 Stata 保存的格式不正确的 118 格式文件 (GH 25960)

  • 改进了 DataFrame.to_html() 中的 col_space 参数,使其接受字符串,以便正确设置 CSS 长度值 (GH 25941)

  • 修复了从 URL 中包含 # 字符的 S3 加载对象的 Bug (GH 25945)

  • read_gbq() 添加了 use_bqstorage_api 参数,以加快大型数据帧的下载速度。此功能需要 pandas-gbq 库的 0.10.0 版本以及 google-cloud-bigquery-storagefastavro 库。(GH 26104)

  • 修复了 DataFrame.to_json() 处理数值数据时的内存泄漏 Bug (GH 24889)

  • read_json() 中一个 Bug,带有 Z 的日期字符串未转换为 UTC 时区 (GH 26168)

  • read_csv() 添加了 cache_dates=True 参数,允许在解析唯一日期时缓存它们 (GH 25990)

  • 当调用者的维度超出 Excel 的限制时,DataFrame.to_excel() 现在会引发 ValueError (GH 26051)

  • 修复了 pandas.read_csv() 中一个 Bug,即使用 engine=’python’ 解析时,BOM 会导致解析不正确 (GH 26545)

  • read_excel() 现在在输入类型为 pandas.io.excel.ExcelFile 且传递了 engine 参数时会引发 ValueError,因为 pandas.io.excel.ExcelFile 已定义了引擎 (GH 26566)

  • 从指定了 where=''HDFStore 选择时出现的 Bug (GH 26610)。

  • 修复了 DataFrame.to_excel() 中一个 Bug,即合并单元格内的自定义对象(如 PeriodIndex)未被转换为对 Excel 写入器安全的类型 (GH 27006)

  • read_hdf() 中一个 Bug,即读取时区感知的 DatetimeIndex 会引发 TypeError (GH 11926)

  • to_msgpack()read_msgpack() 中一个 Bug,即对于无效路径会引发 ValueError 而不是 FileNotFoundError (GH 27160)

  • 修复了 DataFrame.to_parquet() 中当数据帧没有列时会引发 ValueError 的 Bug (GH 27339)

  • 允许在使用 read_csv() 时解析 PeriodDtype 列 (GH 26934)

绘图#

GroupBy/resample/rolling#

  • 修复了 Resampler.agg() 在处理带时区索引时,传入函数列表会引发 OverflowError 的 bug (GH 22660)

  • 修复了 DataFrameGroupBy.nunique() 中丢失列级别名称的 bug (GH 23222)

  • 修复了对带时区数据应用聚合函数时 GroupBy.agg() 中的 bug (GH 23683)

  • 修复了 GroupBy.first()GroupBy.last() 中丢失时区信息的 bug (GH 21603)

  • 修复了仅对 NA 值进行分组时 GroupBy.size() 中的 bug (GH 23050)

  • 修复了 Series.groupby() 中之前忽略 observed 关键字参数的 bug (GH 24880)

  • 修复了 Series.groupby() 中使用 MultiIndex Series 并传入长度等于 series 长度的标签列表时导致分组不正确的 bug (GH 25704)

  • 确保了 groupby 聚合函数在所有 Python 版本中输出顺序一致 (GH 25692)

  • 确保了对有序 Categorical 进行分组并指定 observed=True 时,结果分组顺序正确 (GH 25871, GH 25167)

  • 修复了 Rolling.min()Rolling.max() 中导致内存泄漏的 bug (GH 25893)

  • 修复了 Rolling.count().Expanding.count 中之前忽略 axis 关键字参数的 bug (GH 13503)

  • 修复了 GroupBy.idxmax()GroupBy.idxmin() 在处理日期时间列时返回错误 dtype 的 bug (GH 25444, GH 15306)

  • 修复了 GroupBy.cumsum(), GroupBy.cumprod(), GroupBy.cummin()GroupBy.cummax() 在处理包含缺失类别的分类列时返回错误结果或导致段错误 (segfault) 的 bug (GH 16771)

  • 修复了 GroupBy.nth() 在分组中存在 NA 值时返回错误结果的 bug (GH 26011)

  • 修复了 SeriesGroupBy.transform() 在转换空分组时会引发 ValueError 的 bug (GH 26208)

  • 修复了 DataFrame.groupby() 中,当使用 .groups 访问器时,传入 Grouper 会返回错误分组的 bug (GH 26326)

  • 修复了 GroupBy.agg() 在处理 uint64 列时返回错误结果的 bug。 (GH 26310)

  • 修复了 Rolling.median()Rolling.quantile() 在窗口为空时引发 MemoryError 的 bug (GH 26005)

  • 修复了 Rolling.median()Rolling.quantile() 在使用 closed='left'closed='neither' 时返回错误结果的 bug (GH 26005)

  • 改进了 Rolling, WindowExponentialMovingWindow 函数,使其从结果中排除无关列,而不是引发错误,并且仅在所有列都无关时才引发 DataError (GH 12537)

  • 修复了 Rolling.max()Rolling.min() 在使用空的可变窗口时返回错误结果的 bug (GH 26005)

  • 在使用不支持的加权窗口函数作为 Window.aggregate() 的参数时,引发更有帮助的异常 (GH 26597)

重塑#

  • 修复了 pandas.merge() 在 suffixes 中指定 None 时会添加字符串 None 而不是保留原始列名的 bug (GH 24782)。

  • 修复了 merge() 在按索引名称合并时有时会导致索引编号不正确的 bug (缺失的索引值现在被赋为 NA) (GH 24212, GH 25009)

  • to_records() 现在在其 column_dtypes 参数中接受 dtypes (GH 24895)

  • 修复了 concat() 在将 OrderedDict (以及 Python 3.6+ 中的 dict) 作为 objs 参数传入时未遵循顺序的 bug (GH 21510)

  • 修复了 pivot_table() 中,当 aggfunc 参数包含 list 时,即使 dropna 参数为 False,带有 NaN 值的列仍被丢弃的 bug (GH 22159)

  • 修复了 concat() 中,两个具有相同 freqDatetimeIndex 连接后,结果的 freq 丢失的 bug (GH 3232)。

  • 修复了 merge() 中,当合并等价的 Categorical dtype 时会引发错误的 bug (GH 22501)

  • 修复了使用迭代器或生成器字典实例化 DataFrame (例如 pd.DataFrame({'A': reversed(range(3))})) 会引发错误的 bug (GH 26349)。

  • 修复了使用 range (例如 pd.DataFrame(range(3))) 实例化 DataFrame 会引发错误的 bug (GH 26342)。

  • 修复了 DataFrame 构造函数在传入非空元组时会导致段错误的 bug (GH 25691)

  • 修复了 Series.apply() 在 Series 是带时区的 DatetimeIndex 时失败的 bug (GH 25959)

  • 修复了 pandas.cut() 中,由于整数溢出,较大的 bin 可能错误地引发错误的 bug (GH 26045)

  • 修复了 DataFrame.sort_index() 在多索引 DataFrame 按所有级别排序且初始级别最后排序时引发错误的 bug (GH 26053)

  • 修复了 Series.nlargest()True 视为小于 False 的 bug (GH 26154)

  • 修复了 DataFrame.pivot_table() 在使用 IntervalIndex 作为透视索引时会引发 TypeError 的 bug (GH 25814)

  • 修复了 DataFrame.from_dict()orient='index' 时忽略 OrderedDict 顺序的 bug (GH 8425)。

  • 修复了 DataFrame.transpose() 在转置带有带时区的日期时间列的 DataFrame 时错误地引发 ValueError 的 bug (GH 26825)

  • 修复了 pivot_table() 在将带时区的列作为 values 进行透视时会移除时区信息的 bug (GH 14948)

  • 修复了 merge_asof() 在指定多个 by 列其中一个为 datetime64[ns, tz] dtype 时出现的 bug (GH 26649)

稀疏数据#

  • 显著提高了 SparseArray 初始化速度,这有益于大多数操作,修复了 v0.20.0 中引入的性能回归。(GH 24985)

  • 修复了 SparseFrame 构造函数在将 None 作为数据传入时会忽略 default_fill_value 的 bug (GH 16807)

  • 修复了 SparseDataFrame 在添加列时,如果值的长度与索引长度不匹配,会引发 AssertionError 而不是 ValueError 的 bug (GH 25484)

  • Series.sparse.from_coo() 中引入了更好的错误消息,对于非 coo 矩阵的输入,它现在返回 TypeError (GH 26554)

  • 修复了 numpy.modf()SparseArray 上运行的 bug。现在返回一个由 SparseArray 组成的元组 (GH 26946)。

构建变更#

  • 修复了 PyPy 在 macOS 上安装错误的 bug (GH 26536)

扩展数组#

  • 修复了 factorize() 在传入带有自定义 na_sentinelExtensionArray 时出现的 bug (GH 25696)。

  • Series.count() 对 ExtensionArrays 中的 NA 值计数不准确 (GH 26835)

  • 添加了 Series.__array_ufunc__ 以更好地处理应用于由扩展数组支持的 Series 的 NumPy ufuncs (GH 23293)。

  • ExtensionArray.copy() 中的关键字参数 deep 已被移除 (GH 27083)

其他#

  • 移除了 vendored UltraJSON 实现中未使用的 C 函数 (GH 26198)

  • 允许将 IndexRangeIndex 传递给 numpy 的 minmax 函数 (GH 26125)

  • Series 子类的空对象的 repr 中使用实际类名 (GH 27001)。

  • 修复了 DataFrame 中,传入带时区的 datetime 对象的 object 数组时会错误地引发 ValueError 的 bug (GH 13287)

贡献者#

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

  • 1_x7 +

  • Abdullah İhsan Seçer +

  • Adam Bull +

  • Adam Hooper

  • Albert Villanova del Moral

  • Alex Watt +

  • AlexTereshenkov +

  • Alexander Buchkovsky

  • Alexander Hendorf +

  • Alexander Nordin +

  • Alexander Ponomaroff

  • Alexandre Batisse +

  • Alexandre Decan +

  • Allen Downey +

  • Alyssa Fu Ward +

  • Andrew Gaspari +

  • Andrew Wood +

  • Antoine Viscardi +

  • Antonio Gutierrez +

  • Arno Veenstra +

  • ArtinSarraf

  • Batalex +

  • Baurzhan Muftakhidinov

  • Benjamin Rowell

  • Bharat Raghunathan +

  • Bhavani Ravi +

  • Big Head +

  • Brett Randall +

  • Bryan Cutler +

  • C John Klehm +

  • Caleb Braun +

  • Cecilia +

  • Chris Bertinato +

  • Chris Stadler +

  • Christian Haege +

  • Christian Hudon

  • Christopher Whelan

  • Chuanzhu Xu +

  • Clemens Brunner

  • Damian Kula +

  • Daniel Hrisca +

  • Daniel Luis Costa +

  • Daniel Saxton

  • DanielFEvans +

  • David Liu +

  • Deepyaman Datta +

  • Denis Belavin +

  • Devin Petersohn +

  • Diane Trout +

  • EdAbati +

  • Enrico Rotundo +

  • EternalLearner42 +

  • Evan +

  • Evan Livelo +

  • Fabian Rost +

  • Flavien Lambert +

  • Florian Rathgeber +

  • Frank Hoang +

  • Gaibo Zhang +

  • Gioia Ballin

  • Giuseppe Romagnuolo +

  • Gordon Blackadder +

  • Gregory Rome +

  • Guillaume Gay

  • HHest +

  • Hielke Walinga +

  • How Si Wei +

  • Hubert

  • Huize Wang +

  • Hyukjin Kwon +

  • Ian Dunn +

  • Inevitable-Marzipan +

  • Irv Lustig

  • JElfner +

  • Jacob Bundgaard +

  • James Cobon-Kerr +

  • Jan-Philip Gehrcke +

  • Jarrod Millman +

  • Jayanth Katuri +

  • Jeff Reback

  • Jeremy Schendel

  • Jiang Yue +

  • Joel Ostblom

  • Johan von Forstner +

  • Johnny Chiu +

  • Jonas +

  • Jonathon Vandezande +

  • Jop Vermeer +

  • Joris Van den Bossche

  • Josh

  • Josh Friedlander +

  • Justin Zheng

  • Kaiqi Dong

  • Kane +

  • Kapil Patel +

  • Kara de la Marck +

  • Katherine Surta +

  • Katrin Leinweber +

  • Kendall Masse

  • Kevin Sheppard

  • Kyle Kosic +

  • Lorenzo Stella +

  • Maarten Rietbergen +

  • Mak Sze Chun

  • Marc Garcia

  • Mateusz Woś

  • Matias Heikkilä

  • Mats Maiwald +

  • Matthew Roeschke

  • Max Bolingbroke +

  • Max Kovalovs +

  • Max van Deursen +

  • Michael

  • Michael Davis +

  • Michael P. Moran +

  • Mike Cramblett +

  • Min ho Kim +

  • Misha Veldhoen +

  • Mukul Ashwath Ram +

  • MusTheDataGuy +

  • Nanda H Krishna +

  • Nicholas Musolino

  • Noam Hershtig +

  • Noora Husseini +

  • Paul

  • Paul Reidy

  • Pauli Virtanen

  • Pav A +

  • Peter Leimbigler +

  • Philippe Ombredanne +

  • Pietro Battiston

  • Richard Eames +

  • Roman Yurchak

  • Ruijing Li

  • Ryan

  • Ryan Joyce +

  • Ryan Nazareth

  • Ryan Rehman +

  • Sakar Panta +

  • Samuel Sinayoko

  • Sandeep Pathak +

  • Sangwoong Yoon

  • Saurav Chakravorty

  • Scott Talbert +

  • Sergey Kopylov +

  • Shantanu Gontia +

  • Shivam Rana +

  • Shorokhov Sergey +

  • Simon Hawkins

  • Soyoun(Rose) Kim

  • Stephan Hoyer

  • Stephen Cowley +

  • Stephen Rauch

  • Sterling Paramore +

  • Steven +

  • Stijn Van Hoey

  • Sumanau Sareen +

  • Takuya N +

  • Tan Tran +

  • Tao He +

  • Tarbo Fukazawa

  • Terji Petersen +

  • Thein Oo

  • ThibTrip +

  • Thijs Damsma +

  • Thiviyan Thanapalasingam

  • Thomas A Caswell

  • Thomas Kluiters +

  • Tilen Kusterle +

  • Tim Gates +

  • Tim Hoffmann

  • Tim Swast

  • Tom Augspurger

  • Tom Neep +

  • Tomáš Chvátal +

  • Tyler Reddy

  • Vaibhav Vishal +

  • Vasily Litvinov +

  • Vibhu Agarwal +

  • Vikramjeet Das +

  • Vladislav +

  • Víctor Moron Tejero +

  • Wenhuan

  • Will Ayd +

  • William Ayd

  • Wouter De Coster +

  • Yoann Goular +

  • Zach Angell +

  • alimcmaster1

  • anmyachev +

  • chris-b1

  • danielplawrence +

  • endenis +

  • enisnazif +

  • ezcitron +

  • fjetter

  • froessler

  • gfyoung

  • gwrome +

  • h-vetinari

  • haison +

  • hannah-c +

  • heckeop +

  • iamshwin +

  • jamesoliverh +

  • jbrockmendel

  • jkovacevic +

  • killerontherun1 +

  • knuu +

  • kpapdac +

  • kpflugshaupt +

  • krsnik93 +

  • leerssej +

  • lrjball +

  • mazayo +

  • nathalier +

  • nrebena +

  • nullptr +

  • pilkibun +

  • pmaxey83 +

  • rbenes +

  • robbuckley

  • shawnbrown +

  • sudhir mohanraj +

  • tadeja +

  • tamuhey +

  • thatneat

  • topper-123

  • willweil +

  • yehia67 +

  • yhaque1213 +