0.25.0 中的新增内容(2019 年 7 月 18 日)#

警告

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

警告

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

警告

Panel已被完全删除。对于ND标记的数据结构,请使用xarray

警告

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

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

增强功能#

通过重新标记进行 GroupBy 聚合#

pandas 添加了特殊的 groupby 行为,称为“命名聚合”,用于在将多个聚合函数应用于特定列时命名输出列(GH 18366GH 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]

将所需的列名称作为**kwargsto传递.agg。的值**kwargs 应该是元组,其中第一个元素是列选择,第二个元素是要应用的聚合函数。 pandas 提供了pandas.NamedAggnamedtuple 来更清楚地显示函数的参数是什么,但也接受普通元组。

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]

命名聚合是建议替代已弃用的“dict-of-dicts”方法,用于命名特定于列的聚合的输出(重命名时使用字典弃用 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())。

有关更多信息,请参阅命名聚合。

具有多个 lambda 的 GroupBy 聚合#

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

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所有levels和 ,这在视觉上没有吸引力,并且使输出更难以导航。例如(将范围限制为 5):codesMultiIndex

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

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

Series 和 DataFrame 的较短截断重复#

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

  • 对于小型系列或数据帧,最多max_rows显示行数(默认值:60)。

  • 对于长度大于 的较大系列 DataFrame max_rows,仅 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 16538GH 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 更改#

使用具有 UTC 偏移量的日期字符串进行索引#

使用具有 UTC 偏移量的日期字符串对aDataFrameSeries进行索引之前会忽略 UTC 偏移量。DatetimeIndex现在,索引中会考虑 UTC 偏移量。 (GH 24076GH 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]

MultiIndex由级别和代码构建#

以前允许构造MultiIndex级别或代码值 < -1 的 。NaN现在,不允许使用代码值 < -1 进行构造,并且NaN级别对应的代码将被重新分配为 -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

GroupBy.applyonDataFrame仅对第一组求值一次#

先前的实现DataFrameGroupBy.apply() 在第一组上一致地评估所提供的函数两次,以推断使用快速代码路径是否安全。特别是对于具有副作用的函数,这是一种不受欢迎的行为,并且可能会导致意外。 (GH 2936GH 2656GH 7739GH 10519GH 12155GH 20084GH 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

连接稀疏值#

当传递值稀疏的 DataFrame 时,concat()现在将返回 带有稀疏值的Seriesor DataFrame,而不是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

concat现在,这与onSeries与稀疏值 的现有行为相匹配。当所有值都是 的实例时,concat()将继续返回 a 。SparseDataFrameSparseDataFrame

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

与之前一样,提供任何SparseSeriesSparseDataFrametoconcat()将导致返回SparseSeriesSparseDataFrame

-accessor.str执行更严格的类型检查#

由于缺乏更细粒度的 dtype,Series.str目前仅检查数据是否为object​​dtype。现在将推断系列中的Series.strdtype 数据;特别是, -only 数据将引发异常(除了, , , ),请参阅GH 23163GH 23011GH 23551'bytes'Series.str.decode()Series.str.get()Series.str.len()Series.str.slice()

以前的行为

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

在 GroupBy 期间保留分类数据类型#

以前,分类列(但不是 groupby 键)将object在 groupby 操作期间转换为 dtype。 pandas 现在将保留这些数据类型。 (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)

不兼容的索引类型联合#

在不兼容 dtype 的对象之间执行Index.union()操作时,结果将是Indexdtype 的基数object。此行为适用于Index以前被禁止的对象之间的联合。Index现在将在执行联合操作之前评估空对象的数据类型,而不是简单地返回另一个Index对象。Index.union()现在可以被认为是可交换的,例如(GH 23525)。A.union(B) == B.union(A)

以前的行为

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

请注意,整数和浮点数据类型索引被视为“兼容”。整数值被强制转换为浮点数,这可能会导致精度损失。有关详细信息,请参阅 Index 对象上的 Set 操作

DataFrameGroupBy fill/bfill 不再返回组标签#

ffillbfill和方法之前 在返回值中包含pad了 组标签,这与其他 groupby 转换不一致。现在只返回填充的值。 (GH 21521backfillDataFrameGroupBy

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在空的分类/对象列上进行描述将返回顶部和频率#

DataFrame.describe()使用空分类/对象列进行调用时,之前省略了“top”和“freq”列,这与非空列的输出不一致。现在,“top”和“freq”列将始终包含在内,如果numpy.nan为空DataFrameGH 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 主要在 pandas 对象的 // 方法中定义了字符串表示形式 ,__str__如果未找到 特定方法,则从该方法调用。 Python3 不需要这个。在 pandas 0.25 中,pandas 对象的字符串表示现在通常在 中定义,并且如果特定方法不存在,则通常将调用传递给,这是 Python 的标准。此更改向后兼容 pandas 的直接使用,但如果您对 pandas 对象进行子类化为子类提供特定的/方法,则可能需要调整您的/方法(GH 26495)。__unicode____bytes____str____repr____repr____repr____str____repr____str____str____repr____str____repr__

IntervalIndexInterval对象索引 an #

的索引方法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__) 现在仅返回中True的精确匹配项,而之前会返回中任何重叠的 an 项。IntervalsIntervalIndexTrueIntervalIntervalIntervalIndex

以前的行为

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如果未找到完全匹配,则会引发A。

以前的行为

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表示未找到完全匹配。

这些索引更改扩展到使用索引Series进行查询。DataFrameIntervalIndex

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

使用( ) 或现在仅返回查询的精确匹配Series项。DataFrame[]__getitem__locInterval

以前的行为

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对于不精确匹配,将引发 a 而不是返回重叠匹配。

以前的行为

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

系列上的二进制 ufunc 现在对齐#

当两者都是(GH 23293 )时,应用像现在这样的二进制 ufuncnumpy.power()可以对齐输入。Series

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().要保留先前的行为,请Series在应用 ufunc 之前将另一个转换为数组。

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 时保留列顺序#

dict从 Python 3.7 开始,保证键顺序。实际上,自 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

新行为

dict考虑到从上到下的所有记录,列顺序现在与 中键的插入顺序相匹配。因此,与以前的 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)。如果安装了,我们现在需要:

包裹

最低版本

必需的

麻木

1.13.3

X

皮茨

2015.4

X

python-dateutil

2.6.1

X

瓶颈

1.2.1

数值表达式

2.6.2

pytest(开发)

4.0.2

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

包裹

最低版本

美丽汤4

4.6.0

快速镶木地板

0.2.1

GCSFS

0.2.2

lxml

3.8.0

绘图库

2.2.2

开放式pyxl

2.4.8

皮箭头

0.9.0

pymysql

0.7.1

pytables

3.4.2

scipy

0.19.0

sqlalchemy

1.1.4

阵列

0.8.2

xlrd

1.1.0

XLSX作家

0.9.8

xlwt

1.2.0

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

其他 API 更改#

弃用#

稀疏子类#

SparseSeries和子类SparseDataFrame已弃用。它们的功能最好由具有稀疏值的Series或提供DataFrame

以前的方式

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 格式从 0.25 开始已弃用,并将在未来版本中删除。建议使用 pyarrow 进行 pandas 对象的在线传输。 (GH 27084

其他弃用#

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

性能改进#

  • 初始化显着加速SparseArray,有利于大多数操作,修复了 v0.20.0 中引入的性能回归(GH 24985

  • DataFrame.to_stata()现在,使用任何字符串或非本机字节序列输出数据时速度更快 ( GH 25045 )

  • 改进的性能Series.searchsorted()。当 dtype 为 int8/int16/int32 并且搜索的键位于 dtype 的整数范围内时,加速特别大 ( GH 22034 )

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

  • 改进了切片和其他选定操作的性能RangeIndexGH 26565GH 26617GH 26722

  • RangeIndex现在执行标准查找而不实例化实际的哈希表,因此节省内存(GH 16685

  • read_csv()通过更快的标记化和更快的小浮点数解析来提高性能( GH 25784

  • read_csv()通过更快地解析 N/A 和布尔值来提高性能( GH 25804 )

  • 改进了 的性能IntervalIndex.is_monotonicIntervalIndex.is_monotonic_increasing并删除了( GH 24813 )IntervalIndex.is_monotonic_decreasing的转换MultiIndex

  • 改进了写入日期时间数据类型时的性能DataFrame.to_csv()GH 25708

  • read_csv()通过更快地解析MM/YYYY日期时间格式来提高性能DD/MM/YYYYGH 25922

  • 改进了无法存储 NaN 的数据类型的 nanops 性能。Series.all()Series.any()( GH 25070 )的加速效果尤其突出

  • Series.map()通过映射类别而不是映射所有值,提高了字典映射器在分类系列上的性能( GH 23785

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

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

  • IntervalIndex.is_unique通过删除转换来提高性能MultiIndex( GH 24813 )

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

  • MultiIndex提高了构建至少一个级别时的性能CategoricalIndexGH 22044

  • 通过在检查时消除垃圾收集的需要来提高性能SettingWithCopyWarningGH 27031

  • to_datetime()缓存参数的默认值更改为TrueGH 26043

  • 改进了给定非唯一单调数据的性能DatetimeIndex和切片性能( GH 27136)。PeriodIndex

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

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

Bug修复

分类#

类似日期时间#

  • 当使用遥远的未来日期调用并且指定参数而不是引发时to_datetime(),会引发(不正确)的错误(GH 23830ValueErrorformatOutOfBoundsDatetime

  • 调用时to_datetime()会引发错误,并包含集合中至少两个不同的元素(GH 22305InvalidIndexError: Reindexing only valid with uniquely valued Index objectscache=Truearg{None, numpy.nan, pandas.NaT}

  • 错误DataFrame以及Series时区感知数据dtype='datetime64[ns]未转换为天真的位置(GH 25843

  • 改进了Timestamp各种日期时间函数中的类型检查,以防止使用子类时出现异常datetimeGH 25851

  • Bug inSeriesDataFramerepr wherenp.datetime64('NaT')np.timedelta64('NaT')withdtype=object将表示为NaN( GH 25445 )

  • 当错误设置为强制时to_datetime()不替换无效参数的错误( GH 26122NaT

  • 添加DateOffset非零月份DatetimeIndex会引发错误ValueErrorGH 26258

  • 当使用无效日期和值与and ( GH 25512 )混合调用时,to_datetime()会引发未处理的错误OverflowErrorNaNformat='%Y%m%d'error='coerce'

  • 类似日期时间的索引出现错误isin()DatetimeIndexTimedeltaIndex以及参数被忽略的PeriodIndex地方levels。 (GH 26675

  • 当调用长度 >= 6 位的无效整数日期时to_datetime()引发TypeError的错误format='%Y%m%d'errors='ignore'

  • 将 aPeriodIndex与零维 numpy 数组进行比较时出现错误(GH 26689

  • 使用非 ns 单位和超出范围的时间戳构建垃圾数据的numpy 数组时出现Series错误,现在将正确引发错误(GH 26206)。DataFramedatetime64OutOfBoundsDatetime

  • 对于非常大或非常小的日期date_range()不必要地引发错误( GH 26651OverflowError

  • Timestamp添加到对象会引发错误np.timedelta64而不是返回Timestamp( GH 24775 )

  • 将包含对象的零维 numpy 数组np.datetime64Timestamp错误进行比较的错误TypeErrorGH 26916

  • 调用时to_datetime()会引发错误,包括具有不同偏移量的日期时间字符串(GH 26097ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=Truecache=Truearg

时间增量#

  • 在某些情况下,当实际上存在交集时,TimedeltaIndex.intersection()非单调索引会返回空值(GH 25913Index

  • TimedeltaNaT提升之间的比较错误TypeErrorGH 26039

  • 将 a 添加或减goBusinessHoura 时出现错误Timestamp,结果分别在前一天或后一天着陆(GH 26381

  • 将 aTimedeltaIndex与零维 numpy 数组进行比较时出现错误(GH 26689

时区

数字#

  • to_numeric()大负数处理不当的错误( GH 24910

  • 数字被强制浮动的错误to_numeric(),即使errors不是coerceGH 24910

  • 允许to_numeric()无效值的错误( GH 26466errors

  • format浮点复数未格式化为正确的显示精度和修剪的错误( GH 25514

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

  • Series.divmod()和中的错误Series.rdivmod()会引发(不正确)ValueError而不是返回一对Series对象作为结果(GH 25557

  • interpolate()当使用需要数字索引的方法发送非数字索引时,会引发有用的异常。 (GH 21662

  • 将浮点数与标量运算符进行比较时出现错误eval(),例如:( GH 25928 )x < -0.1

  • 修复了将全布尔数组转换为整数扩展数组失败的错误(GH 25211

  • divmod包含零的对象Series错误地引发错误AttributeErrorGH 26987

  • Series楼层划分 ( // )和用替换( GH 27321 )divmod填充正//零不一致NaNInf

转换

字符串#

间隔

索引#

丢失的

多重索引#

IO #

  • DataFrame.to_html()使用显示选项截断值而不是输出完整内容的错误( GH 17004

  • to_clipboard()修复了在 Windows 上的 Python 3 中使用复制 utf-16 字符时丢失文本的错误( GH 25040 )

  • 当它尝试默认推断 dtypes 时出现错误,这不适用,因为 dtypes 已在 JSON 模式中定义read_json()( GH 21345 )orient='table'

  • read_json()for和 float 索引中的错误orient='table',因为它默认推断索引 dtype,这是不适用的,因为索引 dtype 已在 JSON 模式中定义 ( GH 25433 )

  • read_json()fororient='table'和 float 列名称字符串中的错误,因为它将列名称类型转换为Timestamp,这不适用,因为列名称已在 JSON 模式中定义 ( GH 25435 )

  • json_normalize()输入errors='ignore'数据中缺少的值被填充为DataFrame字符串"nan"而不是numpy.nan( GH 25468 )的错误

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

  • 错误DataFrame.to_string(),当使用关键字DataFrame.to_latex()时会导致错误的输出( GH 16718header

  • read_csv()在 Python 3.6+ 上无法正确解释 Windows 上的 UTF8 编码文件名的错误( GH 15086 )

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

  • 错误:DataFrame.to_html()标题数字在舍入时会忽略显示选项(GH 17280

  • 当通过或参数使用子选择时read_hdf(),从直接使用 PyTables 编写的 HDF5 文件读取表失败并出现错误( GH 11188 )ValueErrorstartstop

  • 在提出read_hdf()a 后无法正确关闭商店的错误( GH 25766KeyError

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

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

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

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

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

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

  • read_json()日期字符串Z未转换为 UTC 时区的错误( GH 26168 )

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

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

  • 修复了pandas.read_csv()BOM 会导致使用 engine='python' 解析不正确的错误(GH 26545

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

  • HDFStore从指定的选项中选择时出现错误where=''GH 26610)。

  • DataFrame.to_excel()修复了合并单元格内的自定义对象(即PeriodIndex)未转换为对 Excel 编写器安全的类型的错误( GH 27006 )

  • read_hdf()读取时区感知DatetimeIndex会引发错误TypeErrorGH 11926

  • to_msgpack()和中的错误read_msgpack()会为无效路径引发 aValueError而不是 a ( GH 27160 )FileNotFoundError

  • 修复了当数据框没有列时DataFrame.to_parquet()会引发的错误( GH 27339ValueError

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

绘图#

GroupBy/重新采样/滚动#

重塑#

稀疏#

  • 初始化显着加速SparseArray,有利于大多数操作,修复了 v0.20.0 中引入的性能回归(GH 24985

  • 构造函数中的错误,作为数据SparseFrame传递会导致被忽略(GH 16807Nonedefault_fill_value

  • 添加一列时出现的错误SparseDataFrame,其中值的长度与索引的长度不匹配,AssertionError会引发而不是引发ValueErrorGH 25484

  • 引入更好的错误消息,以便它为不是 coo 矩阵的输入Series.sparse.from_coo()返回 a ( GH 26554 )TypeError

  • 闯入numpy.modf()一个SparseArray.现在SparseArray返回一个元组( GH 26946)。

构建更改#

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

扩展数组#

  • 传递自定义factorize()时出现错误(GH 25696)。ExtensionArrayna_sentinel

  • Series.count()错误计算 ExtensionArrays 中的 NA 值 ( GH 26835 )

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

  • 关键字参数deep已从ExtensionArray.copy()( GH 27083 )中删除

其他

  • 从供应的 UltraJSON 实现中删除了未使用的 C 函数 ( GH 26198 )

  • 允许IndexRangeIndex传递给 numpyminmax函数(GH 26125

  • 在子类的空对象的 repr 中使用实际的类名SeriesGH 27001)。

  • DataFrame传递时区感知对象的对象数组datetime会错误地引发错误ValueErrorGH 13287

贡献者#

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

  • 1_x7 +

  • 阿卜杜拉·伊赫桑·塞塞尔 +

  • 亚当·布尔 +

  • 亚当·胡珀

  • 阿尔伯特·维拉诺瓦·德尔·莫拉尔

  • 亚历克斯·瓦特 +

  • 亚历克斯·捷列申科夫 +

  • 亚历山大·布赫科夫斯基

  • 亚历山大·亨多夫 +

  • 亚历山大·诺丁 +

  • 亚历山大·波诺马罗夫

  • 亚历山大·巴蒂斯 +

  • 亚历山大·德坎 +

  • 艾伦·唐尼 +

  • 傅艾莉莎·沃德 +

  • 安德鲁·加斯帕里 +

  • 安德鲁·伍德 +

  • 安托万·维斯卡尔迪 +

  • 安东尼奥·古铁雷斯 +

  • 阿诺·文斯特拉 +

  • 阿廷·萨拉夫

  • 巴塔莱克斯+

  • 包尔赞·穆法塔希季诺夫

  • 本杰明·罗威尔

  • 巴拉特·拉古纳坦 +

  • 巴瓦尼·拉维 +

  • 大头+

  • 布雷特·兰德尔 +

  • 布莱恩·卡特勒 +

  • C 约翰·克莱姆 +

  • 迦勒·布劳恩 +

  • 张柏芝+

  • 克里斯·贝尔蒂纳托 +

  • 克里斯·斯塔德勒 +

  • 克里斯蒂安·黑格 +

  • 克里斯蒂安·休顿

  • 克里斯托弗·惠兰

  • 徐传柱 +

  • 克莱门斯·布伦纳

  • 达米安·库拉 +

  • 丹尼尔·赫里斯卡 +

  • 丹尼尔·路易斯·科斯塔 +

  • 丹尼尔·萨克斯顿

  • 丹尼尔·费文斯 +

  • 刘大卫 +

  • 迪普亚曼·达塔 +

  • 丹尼斯·贝拉文 +

  • 德文·彼得森 +

  • 黛安·特劳特 +

  • 埃德阿巴蒂 +

  • 恩里科·罗通多 +

  • 永恒学习者42 +

  • 埃文+

  • 埃文·利弗洛 +

  • 法比安·罗斯特 +

  • 弗拉维安·兰伯特 +

  • 弗洛里安·拉斯格伯 +

  • 弗兰克·黄 +

  • 张盖波+

  • 乔亚·巴林

  • 朱塞佩·罗马尼奥洛 +

  • 戈登·布莱克艾德 +

  • 格雷戈里 罗马 +

  • 纪尧姆·盖伊

  • HHest +

  • 希尔克·瓦林加 +

  • 豪斯威+

  • 休伯特

  • 王慧泽 +

  • 权赫振 +

  • 伊恩·邓恩 +

  • 不可避免-杏仁糖+

  • 欧夫·勒斯蒂格

  • 杰尔夫纳 +

  • 雅各布·邦德加德 +

  • 詹姆斯·科邦-克尔 +

  • 扬·菲利普·格尔克 +

  • 贾罗德·米尔曼 +

  • 贾扬斯·卡图里 +

  • 杰夫·雷巴克

  • 杰里米·申德尔

  • 江悦+

  • 乔尔·奥斯特布洛姆

  • 约翰·冯·福斯特纳 +

  • 约翰尼·赵 +

  • 乔纳斯+

  • 乔纳森·范德赞德 +

  • 乔普·维米尔 +

  • 乔里斯·范登博什

  • 乔什

  • 乔什·弗里德兰德 +

  • 贾斯汀·郑

  • 董凯琪

  • 凯恩+

  • 卡皮尔·帕特尔 +

  • 卡拉·德拉·马克 +

  • 凯瑟琳·苏尔塔 +

  • 卡特琳·莱因韦伯 +

  • 肯德尔·马塞

  • 凯文·谢泼德

  • 凯尔·科西奇 +

  • 洛伦佐·斯特拉 +

  • 马丁·里特贝根 +

  • 麦诗珍

  • 马克·加西亚

  • 马特乌斯·沃斯

  • 马蒂亚斯·海基拉

  • 马茨·迈瓦尔德 +

  • 马修·罗斯克

  • 马克斯·博林布鲁克 +

  • 马克斯·科瓦洛夫斯 +

  • 马克斯·范·德尔森 +

  • 迈克尔

  • 迈克尔·戴维斯 +

  • 迈克尔·P·莫兰 +

  • 迈克·克拉姆布莱特 +

  • 金珉豪+

  • 米莎·维尔德霍恩 +

  • 穆库尔·阿什瓦斯·拉姆 +

  • MusTheDataGuy +

  • 南达·H·克里希纳 +

  • 尼古拉斯·墨索里诺

  • 诺姆·赫什蒂格 +

  • 努拉·侯赛尼 +

  • 保罗

  • 保罗·雷迪

  • 保利·维尔塔宁

  • 帕夫A+

  • 彼得·莱姆比格勒 +

  • 菲利普·翁布雷丹纳 +

  • 彼得罗·巴蒂斯顿

  • 理查德·伊姆斯 +

  • 罗曼·尤尔恰克

  • 李瑞晶

  • 瑞安

  • 瑞恩·乔伊斯 +

  • 瑞安·拿撒勒

  • 瑞安·雷曼 +

  • 萨卡·潘塔 +

  • 塞缪尔·西纳约科

  • 桑迪普·帕塔克 +

  • 尹相雄

  • 索拉夫·查克拉沃蒂

  • 斯科特·塔尔伯特 +

  • 谢尔盖·科佩洛夫 +

  • 尚塔努·贡蒂亚 +

  • 希瓦姆·拉纳 +

  • 谢尔盖·肖罗霍夫 +

  • 西蒙·霍金斯

  • 金素妍 (Rose) Kim

  • 史蒂芬·霍耶

  • 斯蒂芬·考利 +

  • 史蒂芬·劳奇

  • 斯特林帕拉摩尔 +

  • 史蒂文+

  • 斯蒂恩·范霍伊

  • 苏马瑙·萨林 +

  • 拓也N+

  • 谭陈+

  • 何涛+

  • 深泽塔尔博

  • 泰尔吉·彼得森 +

  • 登乌

  • 蒂布旅行+

  • 泰斯·达姆斯玛 +

  • 蒂维扬·塔纳帕拉辛甘

  • 托马斯·卡斯威尔

  • 托马斯·克鲁特斯 +

  • 蒂伦·库斯特勒 +

  • 蒂姆·盖茨 +

  • 蒂姆·霍夫曼

  • 蒂姆·斯瓦斯特

  • 汤姆·奥格斯普格

  • 汤姆·尼普 +

  • 托马斯·查瓦塔尔 +

  • 泰勒·雷迪

  • 瓦伊巴夫·维沙尔 +

  • 瓦西里·李维诺夫 +

  • 维布·阿加瓦尔 +

  • 维克拉姆吉特·达斯 +

  • 弗拉迪斯拉夫+

  • 维克多·莫龙·特赫罗 +

  • 文焕

  • 威尔·艾德 +

  • 威廉·艾德

  • 沃特·德·科斯特 +

  • 约安·古勒 +

  • 扎克·安吉尔 +

  • 阿里姆大师1

  • 安米亚切夫 +

  • 克里斯-B1

  • 丹尼尔·普劳伦斯 +

  • 恩德尼斯+

  • 恩尼西夫+

  • 埃西特伦+

  • 菲耶特

  • 弗勒斯勒

  • 格菲扬

  • 格罗姆 +

  • H-维蒂纳里

  • 海森+

  • 汉娜-C +

  • 赫克奥普+

  • 亚姆什温 +

  • 詹姆斯·索利弗 +

  • 杰布罗克门德尔

  • 伊科瓦切维奇 +

  • 逃亡杀手1 +

  • 克努+

  • 克帕普达克+

  • kpflugshaupt +

  • 克尔斯尼克93 +

  • 莱尔塞伊 +

  • LRJ球 +

  • 马扎约 +

  • 纳塔利尔 +

  • 恩雷贝纳 +

  • 空指针 +

  • 皮尔基文+

  • pmaxey83 +

  • 苯烯+

  • 罗巴克利

  • 肖恩布朗+

  • 苏迪尔·莫汉拉吉 +

  • 塔德哈+

  • 塔穆黑 +

  • 那整齐

  • 礼帽-123

  • 威尔韦尔+

  • 叶海亚67 +

  • yhaque1213 +