Pandas-2-2-中文文档-五十四-

Pandas 2.2 中文文档(五十四)

原文:pandas.pydata.org/docs/

版本 0.19.2(2016 年 12 月 24 日)

原文:pandas.pydata.org/docs/whatsnew/v0.19.2.html

这是 0.19.x 系列中的一个小 bug 修复版本,包括一些小的回归修复、bug 修复和性能改进。我们建议所有用户升级到此版本。

重点包括:

v0.19.2 的新功能

  • 增强功能

  • 性能改进

  • Bug 修复

  • 贡献者

增强功能

pd.merge_asof() 在 0.19.0 版本中添加,进行了一些改进:

  • pd.merge_asof() 增加了 left_index/right_index 和 left_by/right_by 参数(GH 14253)

  • pd.merge_asof() 可以在 by 参数中使用多列,并且具有专门的数据类型以提高性能(GH 13936) ## 性能改进

  • 与 PeriodIndex 的性能回归(GH 14822)

  • 在使用 getitem 进行索引时的性能回归(GH 14930)

  • .replace() 的性能提升(GH 12745)

  • 使用带有日期时间索引和字典数据的 Series 创建的性能提升(GH 14894) ## Bug 修复

  • 与 Python 3.6 兼容,用于一些偏移量的 pickling(GH 14685)

  • 与 Python 3.6 兼容一些索引异常类型(GH 14684, GH 14689)

  • 与 Python 3.6 兼容,用于测试套件中的弃用警告(GH 14681)

  • 与 Python 3.6 兼容,用于 Timestamp 的 pickles(GH 14689)

  • 与 dateutil==2.6.0 兼容;在测试套件中报告了段错误(GH 14621)

  • 允许 Timestamp.replace 中的 nanoseconds 作为关键字参数(GH 14621)

  • pd.read_csv 中的 bug,当将 na_values 作为字典传入时进行了别名处理(GH 14203)

  • pd.read_csv 中的 bug,字典型 na_values 的列索引未被尊重(GH 14203)

  • pd.read_csv 中的 bug,读取文件失败,如果标题的数量等于文件中的行数,则失败(GH 14515)

  • 在 Python 引擎中的pd.read_csv中,当多字符分隔符未被引号尊重时,会引发一个无用的错误消息的 bug(GH 14582)

  • 修复pd.read_sas和pandas.io.sas.sas7bdat.SAS7BDATReader中的 bug(GH 14734,GH 13654),在逐步读取 SAS 文件时导致问题。

  • 在 Python 引擎中的pd.read_csv中,当skipfooter未被 Python 的 CSV 库尊重时,会引发一个无用的错误消息的 bug(GH 13879)

  • 在.fillna()中,时区感知的 datetime64 值被错误地四舍五入的 bug(GH 14872)

  • 在对非词典排序的 MultiIndex 进行.groupby(..., sort=True)时,当使用多个级别进行分组时存在 bug(GH 14776)

  • 在使用负值和单个 bin 的情况下,pd.cut存在 bug(GH 14652)

  • 在pd.to_numeric中,当使用downcast='unsigned'参数时,0 不是无符号的 bug(GH 14401)

  • 在使用共享轴(sharex=True或ax.twinx())绘制常规和不规则时间序列时存在 bug(GH 13341,GH 14322)

  • 在解析无效日期时间时未传播异常的 bug,注意在 Python 3.6 中(GH 14561)

  • 在本地时区的DatetimeIndex中重新采样,涵盖夏令时变更,可能引发AmbiguousTimeError的 bug(GH 14682)

  • 在索引中,将RecursionError转换为KeyError或IndexingError的 bug(GH 14554)

  • 在使用data_columns=True写入MultiIndex时,HDFStore存在 bug(GH 14435)

  • 在使用HDFStore.append()写入Series并传递包含index值的min_itemsize参数时存在 bug(GH 11412)

  • 在使用table格式写入HDFStore时,对index使用min_itemsize值并且没有请求追加时存在 bug(GH 10381)

  • 在Series.groupby.nunique()中,对空Series引发IndexError的 bug(GH 12553)

  • 在DataFrame.nlargest和DataFrame.nsmallest中,当索引具有重复值时存在 bug(GH 13412)

  • 在 Linux 上使用 Python2 时,剪贴板函数存在 bug,涉及 Unicode 和分隔符(GH 13747)

  • Windows 10 和 python 3 上剪贴板功能的错误(GH 14362, GH 12807)

  • .to_clipboard()和 Excel 兼容性的错误(GH 12529)

  • DataFrame.combine_first()对整数列的错误(GH 14687)。

  • 在空数据时pd.read_csv()中dtype参数未被尊重的错误(GH 14712)

  • 在使用 C 引擎解析大型输入时,pd.read_csv()中的nrows参数未被尊重的错误(GH 7626)

  • 在指定容忍度时,pd.merge_asof()中的一个错误无法处理时区感知的 DatetimeIndex(GH 14844)

  • 在写入 doubles 时,to_stata和StataWriter明确检查超出范围的值(GH 14618)

  • .plot(kind='kde')中的错误,它没有删除缺失值以生成 KDE Plot,而是生成了一个空的图表。(GH 14821)

  • 如果以列名列表作为参数调用unstack(),不管所有列的 dtype 是什么,它们都被强制转换为object类型(GH 11847) ## 贡献者

本次发布总共有 33 人贡献了补丁。带有“+”符号的人是第一次贡献补丁的。

  • Ajay Saxena +

  • Ben Kandel

  • Chris

  • Chris Ham +

  • Christopher C. Aycock

  • Daniel Himmelstein +

  • Dave Willmer +

  • Dr-Irv

  • Jeff Carey +

  • Jeff Reback

  • Joe Jevnik

  • Joris Van den Bossche

  • Julian Santander +

  • Kerby Shedden

  • Keshav Ramaswamy

  • Kevin Sheppard

  • Luca Scarabello +

  • Matt Roeschke +

  • Matti Picus +

  • Maximilian Roos

  • Mykola Golubyev +

  • Nate Yoder +

  • Nicholas Ver Halen +

  • Pawel Kordek

  • Pietro Battiston

  • Rodolfo Fernandez +

  • Tara Adiseshan +

  • Tom Augspurger

  • Yaroslav Halchenko

  • gfyoung

  • hesham.shabana@hotmail.com +

  • sinhrks

  • wandersoncferreira + ## 增强功能

pd.merge_asof(),在 0.19.0 版本中添加,增加了一些改进:

  • pd.merge_asof()增加了left_index/right_index和left_by/right_by参数(GH 14253)

  • pd.merge_asof()可以在by参数中使用多个列,并且具有专门的 dtype 以获得更好的性能(GH 13936)

性能改进

  • PeriodIndex的性能回归(GH 14822)

  • 使用getitem进行索引时的性能退化(GH 14930)

  • .replace()的性能改进(GH 12745)

  • 使用字典数据创建带有日期时间索引的 Series 时,性能得到了改进 (GH 14894)。

Bug 修复

  • 兼容 Python 3.6 以对某些偏移进行 pickling 操作 (GH 14685)。

  • 兼容 Python 3.6 的某些索引异常类型 (GH 14684, GH 14689)。

  • 兼容 Python 3.6 的测试套件中的弃用警告 (GH 14681)。

  • 兼容 Python 3.6 以进行时间戳 pickles 操作 (GH 14689)。

  • 兼容 dateutil==2.6.0;测试套件中报告的段错误 (GH 14621)。

  • 允许 Timestamp.replace 中的 nanoseconds 作为关键字参数 (GH 14621)。

  • 在 pd.read_csv 中存在 Bug,当作为字典传递时,na_values 的别名未被处理 (GH 14203)。

  • 在 pd.read_csv 中存在 Bug,当字典样式的 na_values 的列索引未被遵循时 (GH 14203)。

  • 在 pd.read_csv 中存在 Bug,如果标题行数等于文件中的行数,则读取文件失败 (GH 14515)。

  • 在 Python 引擎中的 pd.read_csv 中存在 Bug,当多字符分隔符不受引号保护时,会引发不友好的错误消息 (GH 14582)。

  • 修复了在逐步读取 SAS 文件时导致 pd.read_sas 和 pandas.io.sas.sas7bdat.SAS7BDATReader 中出现问题的 Bug (GH 14734, GH 13654)。

  • 在 Python 引擎中的 pd.read_csv 中存在 Bug,当 skipfooter 未被 Python 的 CSV 库遵循时,会引发不友好的错误消息 (GH 13879)。

  • 在 .fillna() 中存在 Bug,在此处时区感知的 datetime64 值被错误地舍入 (GH 14872)。

  • 非词典排序的多级索引在使用多级分组(.groupby(..., sort=True))时存在 Bug (GH 14776)。

  • 在 pd.cut 中存在 Bug,当有负值和单个 bin 时 (GH 14652)。

  • 在 pd.to_numeric 中存在 Bug,当 downcast='unsigned' 时,0 不是无符号的参数 (GH 14401)。

  • 在使用共享轴绘制正常和不规则时间序列(sharex=True 或 ax.twinx())时存在 Bug (GH 13341, GH 14322)。

  • Bug 未传播在解析无效日期时间时,注意到在 Python 3.6 中(GH 14561)

  • Bug 在本地 TZ 中对DatetimeIndex重新采样时,覆盖了 DST 更改,会引发AmbiguousTimeError(GH 14682)

  • Bug 存在于索引中,将RecursionError转换为KeyError或IndexingError(GH 14554)

  • Bug 存在于HDFStore中,当使用data_columns=True时写入MultiIndex(GH 14435)

  • Bug 存在于HDFStore.append()中,当写入Series并传递包含index值的min_itemsize参数时(GH 11412)

  • Bug 在写入HDFStore到table格式时,使用min_itemsize值为index且不要求附加时(GH 10381)

  • 存在一个 Bug,对于一个空的Series,Series.groupby.nunique()会引发IndexError(GH 12553)

  • Bug 存在于DataFrame.nlargest和DataFrame.nsmallest,当索引具有重复值时(GH 13412)

  • 存在一个 Bug,在具有 Unicode 和分隔符的 python2 的 Linux 上的剪贴板功能中(GH 13747)

  • 存在一个 Bug,在 Windows 10 和 Python 3 上的剪贴板功能中(GH 14362,GH 12807)

  • 存在一个 Bug,在.to_clipboard()和 Excel 兼容性方面(GH 12529)

  • Bug 存在于DataFrame.combine_first()中,用于整数列(GH 14687)。

  • Bug 存在于pd.read_csv()中,当空数据时,dtype参数未被尊重(GH 14712)

  • Bug 存在于pd.read_csv()中,当使用 C 引擎解析大型输入时,nrows参数未被尊重(GH 7626)

  • Bug 存在于pd.merge_asof()中,当指定容差时,无法处理时区感知的 DatetimeIndex(GH 14844)

  • 显式检查在to_stata和StataWriter中,用于写入 doubles 时的超出范围值(GH 14618)

  • Bug 存在于.plot(kind='kde'),未删除缺失值以生成 KDE Plot,而是生成了一个空白图。 (GH 14821)

  • Bug 存在于unstack(),如果以列名列表调用,无论所有列的数据类型如何,都会被强制转换为object(GH 11847)

贡献者

这个版本的贡献者共有 33 人。名字旁边有“+”符号的是第一次贡献补丁的人。

  • Ajay Saxena +

  • Ben Kandel

  • Chris

  • Chris Ham +

  • Christopher C. Aycock

  • Daniel Himmelstein +

  • Dave Willmer +

  • Dr-Irv

  • Jeff Carey +

  • Jeff Reback

  • Joe Jevnik

  • Joris Van den Bossche

  • Julian Santander +

  • Kerby Shedden

  • Keshav Ramaswamy

  • Kevin Sheppard

  • Luca Scarabello +

  • Matt Roeschke +

  • Matti Picus +

  • Maximilian Roos

  • Mykola Golubyev +

  • Nate Yoder +

  • Nicholas Ver Halen +

  • Pawel Kordek

  • Pietro Battiston

  • Rodolfo Fernandez +

  • Tara Adiseshan +

  • Tom Augspurger

  • Yaroslav Halchenko

  • gfyoung

  • hesham.shabana@hotmail.com +

  • sinhrks

  • wandersoncferreira +

版本 0.19.1 (2016 年 11 月 3 日)

原文:pandas.pydata.org/docs/whatsnew/v0.19.1.html

这是从 0.19.0 版本中的一个小 bug 修复版本,包括一些小的回归修复、bug 修复和性能改进。我们建议所有用户升级到此版本。

v0.19.1 的新内容

  • 性能改进

  • 错误修复

  • 贡献者

性能改进

  • 修复了Period数据因子化中的性能回归问题 (GH 14338)

  • 修复了Series.asof(where)中where为标量时的性能回归问题 (GH 14461)

  • 在DataFrame.asof(where)中当where为标量时改进了性能 (GH 14461)

  • 在lines=True时改进了.to_json()的性能 (GH 14408)

  • 在具有 MultiIndex 的某些类型的loc索引中改进了性能 (GH 14551). ## 错误修复

  • 从 PyPI 源安装现在将再次无需安装cython即可工作,与先前版本相同 (GH 14204)

  • 兼容 Cython 0.25 进行构建 (GH 14496)

  • 修复了在read_csv(c 引擎)中关闭用户提供的文件句柄的回归问题 (GH 14418).

  • 修复了当某些列中存在缺失值时DataFrame.quantile中的回归问题 (GH 14357).

  • 修复了Index.difference中DatetimeIndex的freq设置错误的回归问题 (GH 14323)

  • 增加了带有弃用警告的pandas.core.common.array_equivalent (GH 14555).

  • 在 C 引擎中的pd.read_csv中,引号在跳过的行中被错误地解析的 bug (GH 14459)

  • 在 Python 2.x 中的pd.read_csv中存在 Unicode 引号字符不再被尊重的 bug (GH 14477)

  • 修复了在附加分类索引时Index.append中的回归问题 (GH 14545).

  • 修复了当给定具有None值的字典时pd.DataFrame构造函数失败的回归问题 (GH 14381)

  • 修复了当索引为空时DatetimeIndex._maybe_cast_slice_bound中的回归问题 (GH 14354).

  • 当传递布尔值时,本地化模糊时区的 bug (GH 14402)

  • TimedeltaIndex 中的一个错误,使用类似日期时间的对象进行加法运算时,在负方向上的加法溢出未被捕获 (GH 14068, GH 14453)

  • 对具有 object Index 的数据进行字符串索引可能会引发 AttributeError 错误 (GH 14424)

  • 对 pd.eval() 和 df.query() 的空输入正确引发 ValueError 错误 (GH 13139)

  • RangeIndex.intersection 中的一个错误,当结果为空集时 (GH 14364)

  • groupby-transform 中的一个错误,可能导致错误的 dtype 强制转换 (GH 14457)

  • Series.__setitem__ 中的一个错误,允许对只读数组进行变异 (GH 14359)

  • DataFrame.insert 中的一个错误,多次调用带有重复列的函数可能会失败 (GH 14291)

  • 当传递非布尔类型参数时,pd.merge() 将引发 ValueError 错误,传递的布尔类型参数中有非布尔值 (GH 14434)

  • Timestamp 中的一个错误,日期非常接近最小值(1677-09)时可能在创建时下溢 (GH 14415)

  • pd.concat 中的一个错误,keys 的名称未传播到结果的 MultiIndex (GH 14252)

  • pd.concat 中的一个错误,axis 参数无法接受字符串参数 'rows' 或 'columns' (GH 14369)

  • pd.concat 中的一个错误,当数据帧长度不同且元组 keys 时,可能会出现错误 (GH 14438)

  • MultiIndex.set_levels 中的一个错误,在引发错误后仍会设置非法级别值 (GH 13754)

  • DataFrame.to_json 中的一个错误,lines=True 并且值包含 } 字符 (GH 14391)

  • df.groupby 中的一个错误,当将单索引帧按列分组且索引级别时,可能会引发 AttributeError 错误 (GH 14327)

  • df.groupby 中的一个错误,当传入列表时,传递 pd.Grouper(key=...) 可能会引发 TypeError 错误 (GH 14334)

  • pd.pivot_table 中的一个错误,当 index 或 columns 不是标量且未指定 values 时,可能会引发 TypeError 或 ValueError 错误 (GH 14380) ## 贡献者

总共有 30 人为此版本贡献了补丁。带有“+”标记的人首次为此版本贡献了补丁。

  • Adam Chainz +

  • Anthonios Partheniou

  • Arash Rouhani +

  • Ben Kandel

  • Brandon M. Burroughs +

  • Chris

  • Chris Warth

  • David Krych +

  • Iván Vallés Pérez +

  • Jeff Reback

  • Joe Jevnik

  • Jon M. Mease +

  • Jon Mease +

  • Joris Van den Bossche

  • Josh Owen +

  • Keshav Ramaswamy +

  • Larry Ren +

  • Michael Felt +

  • Piotr Chromiec +

  • Robert Bradshaw +

  • Sinhrks

  • Thiago Serafim +

  • Tom Bird

  • bkandel +

  • chris-b1

  • dubourg +

  • gfyoung

  • mattrijk +

  • paul-mannino +

  • sinhrks ## 性能改进

  • 修复了Period数据因子化中的性能回归(GH 14338)

  • 修复了Series.asof(where)中的性能回归,当where是标量时(GH 14461)

  • 在DataFrame.asof(where)中的性能改进,当where是标量时(GH 14461)

  • 在.to_json()中改进了性能,当lines=True时(GH 14408)

  • 在某些类型的loc索引中提高了性能,具有多重索引(GH 14551)

Bug fixes

  • 从 PyPI 进行源安装现在将再次在没有安装cython的情况下工作,就像以前的版本一样(GH 14204)

  • 与 Cython 0.25 兼容以进行构建(GH 14496)

  • 修复了在read_csv(c 引擎)中关闭用户提供的文件句柄的回归(GH 14418)

  • 修复了DataFrame.quantile中的回归,当某些列中存在缺失值时(GH 14357)

  • 修复了Index.difference中的回归,其中DatetimeIndex的freq被错误设置(GH 14323)

  • 添加了pandas.core.common.array_equivalent,并附有弃用警告(GH 14555)

  • 修复了pd.read_csv中 C 引擎的一个错误,即在跳过的行中引号被错误解析(GH 14459)

  • 修复了pd.read_csv中 Python 2.x 的错误,即不再尊重 Unicode 引号字符(GH 14477)

  • 修复了Index.append中的回归,当附加分类索引时(GH 14545)

  • 修复了pd.DataFrame中的回归,当给定带有None值的字典时构造函数失败(GH 14381)

  • 修复了DatetimeIndex._maybe_cast_slice_bound中的回归,当索引为空时(GH 14354)

  • 在传递布尔值时本地化模糊时区的错误修复(GH 14402)

  • 修复了TimedeltaIndex与类似日期时间对象相加时,在负方向上的加法溢出未被捕获的错误(GH 14068,GH 14453)

  • 在针对带有 object Index 的数据进行字符串索引时可能引发 AttributeError 的 bug (GH 14424)

  • 在 pd.eval() 和 df.query() 的空输入上正确引发 ValueError (GH 13139)

  • 修复了 RangeIndex.intersection 在结果为空集时的 bug (GH 14364).

  • 修复了在分组转换广播中可能导致错误的 dtype 强制转换的 bug (GH 14457)

  • 修复了允许修改只读数组的 Series.__setitem__ 中的 bug (GH 14359).

  • 修复了 DataFrame.insert 中的 bug,多次调用并包含重复列名时可能失败 (GH 14291)

  • 在传递布尔类型参数时,pd.merge() 将引发 ValueError (GH 14434)

  • 修复了 Timestamp 中的 bug,创建时日期非常接近最小值 (1677-09) 时可能下溢 (GH 14415)

  • 修复了 pd.concat 中的 bug,keys 的名称未传播到结果的 MultiIndex 中 (GH 14252)

  • 修复了 pd.concat 中的 bug,axis 不能接受字符串参数 'rows' 或 'columns' (GH 14369)

  • 修复了 pd.concat 中的 bug,处理长度不同且元组 keys 的 dataframe 时可能出错 (GH 14438)

  • 修复了 MultiIndex.set_levels 中的 bug,错误级别值在引发错误后仍然设置 (GH 13754)

  • 修复了 DataFrame.to_json 中的 bug,其中 lines=True 并且一个值包含 } 字符时 (GH 14391)

  • 修复了 df.groupby 中的 bug,在将单索引帧按列分组并索引级别时引发 AttributeError (GH 14327)

  • 修复了 df.groupby 中的 bug,当传递 pd.Grouper(key=...) 列表时可能引发 TypeError (GH 14334)

  • 修复了 pd.pivot_table 中的 bug,在未指定 values 的情况下,当 index 或 columns 不是标量时可能引发 TypeError 或 ValueError (GH 14380)

贡献者

本版本共有 30 人贡献了补丁。姓名后面有 “+” 表示是第一次贡献补丁。

  • Adam Chainz +

  • Anthonios Partheniou

  • Arash Rouhani +

  • Ben Kandel

  • Brandon M. Burroughs +

  • Chris

  • Chris Warth

  • David Krych +

  • Iván Vallés Pérez +

  • Jeff Reback

  • Joe Jevnik

  • Jon M. Mease +

  • Jon Mease +

  • Joris Van den Bossche

  • Josh Owen +

  • Keshav Ramaswamy +

  • Larry Ren +

  • Michael Felt +

  • Piotr Chromiec +

  • Robert Bradshaw +

  • Sinhrks

  • Thiago Serafim +

  • Tom Bird

  • bkandel +

  • chris-b1

  • dubourg +

  • gfyoung

  • mattrijk +

  • paul-mannino +

  • sinhrks

版本 0.19.0(2016 年 10 月 2 日)

原文:pandas.pydata.org/docs/whatsnew/v0.19.0.html

这是从 0.18.1 开始的一个重大发布,包括许多 API 更改,几个新功能,增强功能和性能改进以及大量的错误修复。我们建议所有用户升级到此版本。

主要亮点包括:

  • merge_asof() 用于 asof 风格的时间序列连接,请参见此处

  • .rolling() 现在具有时间序列的意识,请参见此处

  • read_csv() 现在支持解析Categorical数据,请参见此处

  • 添加了一个函数union_categorical()用于组合分类变量,请参见此处

  • PeriodIndex 现在具有自己的 period dtype,并且更改为与其他 Index 类更一致。请参见此处

  • 稀疏数据结构增强了对int和bool dtypes 的支持,请参见此处

  • Series 的比较操作不再忽略索引,请参见此处以了解 API 更改的概述。

  • 引入了 pandas 开发 API 用于实用函数,请参见此处。

  • 弃用 Panel4D 和 PanelND。我们建议使用xarray package来表示这些类型的 n 维数据。

  • 删除以前弃用的模块 pandas.io.data,pandas.io.wb,pandas.tools.rplot。

警告

pandas >= 0.19.0 不再在导入时消除 numpy ufunc 警告,请参见此处。

v0.19.0 中的新内容

  • 新功能

    • 函数merge_asof用于 asof 风格的时间序列连接

    • 方法.rolling()现在具有时间序列的意识

    • 方法read_csv对重复列名的支持改进

    • 方法read_csv支持直接解析Categorical

    • 分类拼接

    • 半月偏移量

    • 新的索引方法

    • Google BigQuery 增强功能

    • 细粒度的 NumPy errstate

    • 方法get_dummies现在返回整数 dtypes

    • 将值转换为to_numeric中可能的最小 dtype

    • pandas 开发 API

    • 其他增强功能

  • API 更改

    • Series.tolist()现在将返回 Python 类型

    • Series在不同索引上的运算符

      • 算术运算符

      • 比较运算符

      • 逻辑运算符

      • 灵活的比较方法

    • Series赋值时类型提升

    • 函数.to_datetime()变更

    • 合并变更

    • 方法.describe()的变更

    • Period变更

      • PeriodIndex现在具有period dtype

      • Period('NaT')现在返回pd.NaT

      • PeriodIndex.values现在返回Period对象数组

    • 索引+ / -不再用于集合操作

    • Index.difference和.symmetric_difference变更

    • Index.unique一致返回Index

    • MultiIndex构造函数,groupby和set_index保留分类 dtype

    • 函数read_csv将逐步枚举块

    • 稀疏变更

      • 类型int64和bool支持增强

      • 运算符现在保留 dtypes

      • 其他稀疏修复

    • 索引器 dtype 变更

    • 其他 API 更改

  • 弃用

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

  • 性能改进

  • 错误修复

  • 贡献者

新功能

函数merge_asof用于 asof 风格的时间序列连接

通过merge_asof()函数添加了一个长期请求的功能,支持 asof 风格的时间序列连接(GH 1870,GH 13695,GH 13709,GH 13902)。完整文档在这里。

merge_asof()函数执行 asof 合并,类似于左连接,只是我们匹配最近的键而不是相等的键。

In [1]: left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]})

In [2]: right = pd.DataFrame({"a": [1, 2, 3, 6, 7], "right_val": [1, 2, 3, 6, 7]})

In [3]: left
Out[3]: 
 a left_val
0   1        a
1   5        b
2  10        c

[3 rows x 2 columns]

In [4]: right
Out[4]: 
 a  right_val
0  1          1
1  2          2
2  3          3
3  6          6
4  7          7

[5 rows x 2 columns] 

我们通常希望尽可能精确匹配,并在可能时使用最新值。

In [5]: pd.merge_asof(left, right, on="a")
Out[5]: 
 a left_val  right_val
0   1        a          1
1   5        b          3
2  10        c          7

[3 rows x 3 columns] 

我们还可以仅与先前数据匹配行,而不是完全匹配。

In [6]: pd.merge_asof(left, right, on="a", allow_exact_matches=False)
Out[6]: 
 a left_val  right_val
0   1        a        NaN
1   5        b        3.0
2  10        c        7.0

[3 rows x 3 columns] 

在典型的时间序列示例中,我们有trades和quotes,我们想要asof-join它们。这也说明了在合并之前对数据进行分组的by参数的使用。

In [7]: trades = pd.DataFrame(
 ...:    {
 ...:        "time": pd.to_datetime(
 ...:            [
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.038",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.048",
 ...:            ]
 ...:        ),
 ...:        "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"],
 ...:        "price": [51.95, 51.95, 720.77, 720.92, 98.00],
 ...:        "quantity": [75, 155, 100, 100, 100],
 ...:    },
 ...:    columns=["time", "ticker", "price", "quantity"],
 ...: )
 ...: 

In [8]: quotes = pd.DataFrame(
 ...:    {
 ...:        "time": pd.to_datetime(
 ...:            [
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.030",
 ...:                "20160525 13:30:00.041",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.049",
 ...:                "20160525 13:30:00.072",
 ...:                "20160525 13:30:00.075",
 ...:            ]
 ...:        ),
 ...:        "ticker": ["GOOG", "MSFT", "MSFT", "MSFT", "GOOG", "AAPL", "GOOG", "MSFT"],
 ...:        "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
 ...:        "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03],
 ...:    },
 ...:    columns=["time", "ticker", "bid", "ask"],
 ...: )
 ...: 
In [9]: trades
Out[9]: 
 time ticker   price  quantity
0 2016-05-25 13:30:00.023   MSFT   51.95        75
1 2016-05-25 13:30:00.038   MSFT   51.95       155
2 2016-05-25 13:30:00.048   GOOG  720.77       100
3 2016-05-25 13:30:00.048   GOOG  720.92       100
4 2016-05-25 13:30:00.048   AAPL   98.00       100

[5 rows x 4 columns]

In [10]: quotes
Out[10]: 
 time ticker     bid     ask
0 2016-05-25 13:30:00.023   GOOG  720.50  720.93
1 2016-05-25 13:30:00.023   MSFT   51.95   51.96
2 2016-05-25 13:30:00.030   MSFT   51.97   51.98
3 2016-05-25 13:30:00.041   MSFT   51.99   52.00
4 2016-05-25 13:30:00.048   GOOG  720.50  720.93
5 2016-05-25 13:30:00.049   AAPL   97.99   98.01
6 2016-05-25 13:30:00.072   GOOG  720.50  720.88
7 2016-05-25 13:30:00.075   MSFT   52.01   52.03

[8 rows x 4 columns] 

asof合并在on上进行,通常是一个日期时间字段,它是有序的,在这种情况下,我们在by字段中使用了一个分组器。这类似于左外连接,但是前向填充会自动发生,取最近的非 NaN 值。

In [11]: pd.merge_asof(trades, quotes, on="time", by="ticker")
Out[11]: 
 time ticker   price  quantity     bid     ask
0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN

[5 rows x 6 columns] 

这将返回一个合并的 DataFrame,其中条目与原始左传 DataFrame(在本例中是trades)的顺序相同,字段为合并的quotes。 ### 方法.rolling()现在具有时间序列意识

.rolling()对象现在具有时间序列意识,并且可以接受时间序列偏移(或可转换为其)作为window参数(GH 13327,GH 12995)。请参阅完整文档此处。

In [12]: dft = pd.DataFrame(
 ....:    {"B": [0, 1, 2, np.nan, 4]},
 ....:    index=pd.date_range("20130101 09:00:00", periods=5, freq="s"),
 ....: )
 ....: 

In [13]: dft
Out[13]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  2.0
2013-01-01 09:00:03  NaN
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

这是一个常规频率索引。使用整数窗口参数沿窗口频率滚动有效。

In [14]: dft.rolling(2).sum()
Out[14]: 
 B
2013-01-01 09:00:00  NaN
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  NaN
2013-01-01 09:00:04  NaN

[5 rows x 1 columns]

In [15]: dft.rolling(2, min_periods=1).sum()
Out[15]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

指定偏移量允许更直观地指定滚动频率。

In [16]: dft.rolling("2s").sum()
Out[16]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

使用非常规但仍然单调的索引,使用整数窗口滚动不会产生任何特殊的计算。

In [17]: dft = pd.DataFrame(
 ....:    {"B": [0, 1, 2, np.nan, 4]},
 ....:    index=pd.Index(
 ....:        [
 ....:            pd.Timestamp("20130101 09:00:00"),
 ....:            pd.Timestamp("20130101 09:00:02"),
 ....:            pd.Timestamp("20130101 09:00:03"),
 ....:            pd.Timestamp("20130101 09:00:05"),
 ....:            pd.Timestamp("20130101 09:00:06"),
 ....:        ],
 ....:        name="foo",
 ....:    ),
 ....: )
 ....: 

In [18]: dft
Out[18]: 
 B
foo 
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  4.0

[5 rows x 1 columns]

In [19]: dft.rolling(2).sum()
Out[19]: 
 B
foo 
2013-01-01 09:00:00  NaN
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  NaN

[5 rows x 1 columns] 

使用时间规范为这些稀疏数据生成可变窗口。

In [20]: dft.rolling("2s").sum()
Out[20]: 
 B
foo 
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  4.0

[5 rows x 1 columns] 

此外,我们现在允许可选的on参数来指定 DataFrame 中的列(而不是默认的索引)。

In [21]: dft = dft.reset_index()

In [22]: dft
Out[22]: 
 foo    B
0 2013-01-01 09:00:00  0.0
1 2013-01-01 09:00:02  1.0
2 2013-01-01 09:00:03  2.0
3 2013-01-01 09:00:05  NaN
4 2013-01-01 09:00:06  4.0

[5 rows x 2 columns]

In [23]: dft.rolling("2s", on="foo").sum()
Out[23]: 
 foo    B
0 2013-01-01 09:00:00  0.0
1 2013-01-01 09:00:02  1.0
2 2013-01-01 09:00:03  3.0
3 2013-01-01 09:00:05  NaN
4 2013-01-01 09:00:06  4.0

[5 rows x 2 columns] 
```  ### 方法`read_csv`已经改进了对重复列名的支持

重复列名现在在`read_csv()`中得到支持,无论它们是在文件中还是作为`names`参数传递([GH 7160](https://github.com/pandas-dev/pandas/issues/7160),[GH 9424](https://github.com/pandas-dev/pandas/issues/9424))

```py
In [24]: data = "0,1,2\n3,4,5"

In [25]: names = ["a", "b", "a"] 

先前的行为:

In [2]: pd.read_csv(StringIO(data), names=names)
Out[2]:
 a  b  a
0  2  1  2
1  5  4  5 

第一个a列包含了与第二个a列相同的数据,而它应该包含值[0, 3]。

新行为:

In [26]: pd.read_csv(StringIO(data), names=names)
---------------------------------------------------------------------------
ValueError  Traceback (most recent call last)
Cell In[26], line 1
----> 1 pd.read_csv(StringIO(data), names=names)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:1026, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)
  1013 kwds_defaults = _refine_defaults_read(
  1014     dialect,
  1015     delimiter,
   (...)
  1022     dtype_backend=dtype_backend,
  1023 )
  1024 kwds.update(kwds_defaults)
-> 1026 return _read(filepath_or_buffer, kwds)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:617, in _read(filepath_or_buffer, kwds)
  614 nrows = kwds.get("nrows", None)
  616 # Check for duplicates in names.
--> 617 _validate_names(kwds.get("names", None))
  619 # Create the parser.
  620 parser = TextFileReader(filepath_or_buffer, **kwds)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:576, in _validate_names(names)
  574 if names is not None:
  575     if len(names) != len(set(names)):
--> 576         raise ValueError("Duplicate names are not allowed.")
  577     if not (
  578         is_list_like(names, allow_sets=False) or isinstance(names, abc.KeysView)
  579     ):
  580         raise ValueError("Names should be an ordered collection.")

ValueError: Duplicate names are not allowed. 
```  ### 方法`read_csv`直接支持解析`Categorical`

当指定为 dtype 时,`read_csv()`函数现在支持解析`Categorical`列([GH 10153](https://github.com/pandas-dev/pandas/issues/10153))。根据数据的结构,这可以导致比解析后转换为`Categorical`更快的解析时间和更低的内存使用率。请参阅此处的 io 文档。

```py
In [27]: data = """
 ....: col1,col2,col3
 ....: a,b,1
 ....: a,b,2
 ....: c,d,3
 ....: """
 ....: 

In [28]: pd.read_csv(StringIO(data))
Out[28]: 
 col1 col2  col3
0    a    b     1
1    a    b     2
2    c    d     3

[3 rows x 3 columns]

In [29]: pd.read_csv(StringIO(data)).dtypes
Out[29]: 
col1    object
col2    object
col3     int64
Length: 3, dtype: object

In [30]: pd.read_csv(StringIO(data), dtype="category").dtypes
Out[30]: 
col1    category
col2    category
col3    category
Length: 3, dtype: object 

可以使用字典规范将各个列解析为Categorical

In [31]: pd.read_csv(StringIO(data), dtype={"col1": "category"}).dtypes
Out[31]: 
col1    category
col2      object
col3       int64
Length: 3, dtype: object 

注意

结果类别将始终被解析为字符串(object dtype)。如果类别是数字,则可以使用to_numeric()函数进行转换,或者使用其他适当的转换器,如to_datetime()。

In [32]: df = pd.read_csv(StringIO(data), dtype="category")

In [33]: df.dtypes
Out[33]: 
col1    category
col2    category
col3    category
Length: 3, dtype: object

In [34]: df["col3"]
Out[34]: 
0    1
1    2
2    3
Name: col3, Length: 3, dtype: category
Categories (3, object): ['1', '2', '3']

In [35]: new_categories = pd.to_numeric(df["col3"].cat.categories)

In [36]: df["col3"] = df["col3"].cat.rename_categories(new_categories)

In [37]: df["col3"]
Out[37]: 
0    1
1    2
2    3
Name: col3, Length: 3, dtype: category
Categories (3, int64): [1, 2, 3] 
```  ### 类别连接

+   已添加一个名为 `union_categoricals()` 的函数,用于组合类别,参见类别组合([GH 13361](https://github.com/pandas-dev/pandas/issues/13361)、[GH 13763](https://github.com/pandas-dev/pandas/issues/13763)、[GH 13846](https://github.com/pandas-dev/pandas/issues/13846)、[GH 14173](https://github.com/pandas-dev/pandas/issues/14173))。

    ```py
    In [38]: from pandas.api.types import union_categoricals

    In [39]: a = pd.Categorical(["b", "c"])

    In [40]: b = pd.Categorical(["a", "b"])

    In [41]: union_categoricals([a, b])
    Out[41]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['b', 'c', 'a'] 
    ```

+   `concat` 和 `append` 现在可以将不同 `categories` 的 `category` 数据类型连接为 `object` 数据类型([GH 13524](https://github.com/pandas-dev/pandas/issues/13524))。

    ```py
    In [42]: s1 = pd.Series(["a", "b"], dtype="category")

    In [43]: s2 = pd.Series(["b", "c"], dtype="category") 
    ```

**先前的行为**:

```py
In [1]: pd.concat([s1, s2])
ValueError: incompatible categories in categorical concat 

新行为:

In [44]: pd.concat([s1, s2])
Out[44]: 
0    a
1    b
0    b
1    c
Length: 4, dtype: object 
```  ### 半月偏移

pandas 现在增加了新的频率偏移,`SemiMonthEnd`(‘SM’)和 `SemiMonthBegin`(‘SMS’)。这些提供了默认情况下锚定到月份的 15 日和月底,以及分别锚定到月份的 15 日和月初的日期偏移([GH 1543](https://github.com/pandas-dev/pandas/issues/1543))。

```py
In [45]: from pandas.tseries.offsets import SemiMonthEnd, SemiMonthBegin 

半月末:

In [46]: pd.Timestamp("2016-01-01") + SemiMonthEnd()
Out[46]: Timestamp('2016-01-15 00:00:00')

In [47]: pd.date_range("2015-01-01", freq="SM", periods=4)
Out[47]: DatetimeIndex(['2015-01-15', '2015-01-31', '2015-02-15', '2015-02-28'], dtype='datetime64[ns]', freq='SM-15') 

半月初:

In [46]: pd.Timestamp("2016-01-01") + SemiMonthBegin()
Out[46]: Timestamp('2016-01-15 00:00:00')

In [47]: pd.date_range("2015-01-01", freq="SMS", periods=4)
Out[47]: DatetimeIndex(['2015-01-01', '2015-01-15', '2015-02-01', '2015-02-15'], dtype='datetime64[ns]', freq='SMS-15') 

使用定位后缀,您还可以指定要使用的月份的日期,而不是 15 日。

In [50]: pd.date_range("2015-01-01", freq="SMS-16", periods=4)
Out[50]: DatetimeIndex(['2015-01-01', '2015-01-16', '2015-02-01', '2015-02-16'], dtype='datetime64[ns]', freq='SMS-16')

In [51]: pd.date_range("2015-01-01", freq="SM-14", periods=4)
Out[51]: DatetimeIndex(['2015-01-14', '2015-01-31', '2015-02-14', '2015-02-28'], dtype='datetime64[ns]', freq='SM-14') 
```  ### 新的索引方法

下列方法和选项已添加到 `Index` 中,以使其与 `Series` 和 `DataFrame` API 更加一致。

`Index` 现在支持 `.where()` 函数进行相同形状的索引([GH 13170](https://github.com/pandas-dev/pandas/issues/13170))。

```py
In [48]: idx = pd.Index(["a", "b", "c"])

In [49]: idx.where([True, False, True])
Out[49]: Index(['a', None, 'c'], dtype='object') 

Index 现在支持 .dropna() 以排除缺失值(GH 6194)。

In [50]: idx = pd.Index([1, 2, np.nan, 4])

In [51]: idx.dropna()
Out[51]: Index([1.0, 2.0, 4.0], dtype='float64') 

对于 MultiIndex,默认情况下,如果任何级别缺失,则会删除值。指定 how='all' 仅在所有级别都缺失时才删除值。

In [52]: midx = pd.MultiIndex.from_arrays([[1, 2, np.nan, 4], [1, 2, np.nan, np.nan]])

In [53]: midx
Out[53]: 
MultiIndex([(1.0, 1.0),
 (2.0, 2.0),
 (nan, nan),
 (4.0, nan)],
 )

In [54]: midx.dropna()
Out[54]: 
MultiIndex([(1, 1),
 (2, 2)],
 )

In [55]: midx.dropna(how="all")
Out[55]: 
MultiIndex([(1, 1.0),
 (2, 2.0),
 (4, nan)],
 ) 

Index 现在支持 .str.extractall(),返回一个 DataFrame,请参阅这里的文档(GH 10008、GH 13156)。

In [56]: idx = pd.Index(["a1a2", "b1", "c1"])

In [57]: idx.str.extractall(r"ab")
Out[57]: 
 digit
 match 
0 0         1
 1         2
1 0         1

[3 rows x 1 columns] 

Index.astype() 现在接受一个可选的布尔参数 copy,如果满足 dtype 的要求,则允许可选复制(GH 13209) ### Google BigQuery 增强

  • read_gbq() 方法已经增加了 dialect 参数,允许用户指定是否使用 BigQuery 的传统 SQL 或 BigQuery 的标准 SQL。有关更多详情,请参阅文档(GH 13615)。

  • to_gbq() 方法现在允许 DataFrame 列顺序与目标表模式不同 (GH 11359). ### 细粒度的 NumPy errstate

在之前的 pandas 版本中,当导入 pandas 时,会永久性地关闭 numpy 的 ufunc 错误处理。pandas 这样做是为了消除使用 numpy ufuncs 处理缺失数据时产生的警告,这些数据通常表示为 NaN。不幸的是,这样做会消除应用程序中非 pandas 代码中出现的合法警告。从 0.19.0 开始,pandas 将使用 numpy.errstate 上下文管理器以更精细的方式消除这些警告,仅在 pandas 代码库中实际使用这些操作的地方附近。(GH 13109, GH 13145)

升级 pandas 后,你可能会看到新的 RuntimeWarnings 从你的代码中发出。这些很可能是合法的,并且在使用之前版本的 pandas 时存在于代码中的潜在原因只是简单地消除了警告。在 RuntimeWarning 的源代码周围使用 numpy.errstate 来控制如何处理这些条件。### 方法 get_dummies 现在返回整数数据类型

pd.get_dummies 函数现在返回小整数编码的列,而不是浮点数 (GH 8725)。这应该提供了更好的内存占用。

以前的行为:

In [1]: pd.get_dummies(['a', 'b', 'a', 'c']).dtypes

Out[1]:
a    float64
b    float64
c    float64
dtype: object 

新行为:

In [58]: pd.get_dummies(["a", "b", "a", "c"]).dtypes
Out[58]: 
a    bool
b    bool
c    bool
Length: 3, dtype: object 
```  ### 将值下转为可能的最小 dtype 在 `to_numeric`

`pd.to_numeric()` 现在接受一个 `downcast` 参数,如果可能的话将数据下转为指定的最小数值 dtype ([GH 13352](https://github.com/pandas-dev/pandas/issues/13352))

```py
In [59]: s = ["1", 2, 3]

In [60]: pd.to_numeric(s, downcast="unsigned")
Out[60]: array([1, 2, 3], dtype=uint8)

In [61]: pd.to_numeric(s, downcast="integer")
Out[61]: array([1, 2, 3], dtype=int8) 
```  ### pandas 开发 API

作为使 pandas API 在未来更加统一和易于访问的一部分,我们创建了一个标准的 pandas 子包,`pandas.api`,用于保存公共 API。我们首先在 `pandas.api.types` 中公开了类型内省函数。将来的 pandas 版本中将发布更多子包和官方认可的 API ([GH 13147](https://github.com/pandas-dev/pandas/issues/13147), [GH 13634](https://github.com/pandas-dev/pandas/issues/13634))

以下内容现已成为此 API 的一部分:

```py
In [62]: import pprint

In [63]: from pandas.api import types

In [64]: funcs = [f for f in dir(types) if not f.startswith("_")]

In [65]: pprint.pprint(funcs)
['CategoricalDtype',
 'DatetimeTZDtype',
 'IntervalDtype',
 'PeriodDtype',
 'infer_dtype',
 'is_any_real_numeric_dtype',
 'is_array_like',
 'is_bool',
 'is_bool_dtype',
 'is_categorical_dtype',
 'is_complex',
 'is_complex_dtype',
 'is_datetime64_any_dtype',
 'is_datetime64_dtype',
 'is_datetime64_ns_dtype',
 'is_datetime64tz_dtype',
 'is_dict_like',
 'is_dtype_equal',
 'is_extension_array_dtype',
 'is_file_like',
 'is_float',
 'is_float_dtype',
 'is_hashable',
 'is_int64_dtype',
 'is_integer',
 'is_integer_dtype',
 'is_interval',
 'is_interval_dtype',
 'is_iterator',
 'is_list_like',
 'is_named_tuple',
 'is_number',
 'is_numeric_dtype',
 'is_object_dtype',
 'is_period_dtype',
 'is_re',
 'is_re_compilable',
 'is_scalar',
 'is_signed_integer_dtype',
 'is_sparse',
 'is_string_dtype',
 'is_timedelta64_dtype',
 'is_timedelta64_ns_dtype',
 'is_unsigned_integer_dtype',
 'pandas_dtype',
 'union_categoricals'] 

注意

从内部模块 pandas.core.common 调用这些函数现在会显示一个 DeprecationWarning (GH 13990) ### 其他增强功能

  • Timestamp 现在可以接受类似于 datetime.datetime() 的位置和关键字参数 (GH 10758, GH 11630)

    In [66]: pd.Timestamp(2012, 1, 1)
    Out[66]: Timestamp('2012-01-01 00:00:00')
    
    In [67]: pd.Timestamp(year=2012, month=1, day=1, hour=8, minute=30)
    Out[67]: Timestamp('2012-01-01 08:30:00') 
    
  • .resample() 函数现在接受 on= 或 level= 参数,用于在日期时间列或 MultiIndex 级别上重新采样 (GH 13500)。

    In [68]: df = pd.DataFrame(
     ....:    {"date": pd.date_range("2015-01-01", freq="W", periods=5), "a": np.arange(5)},
     ....:    index=pd.MultiIndex.from_arrays(
     ....:        [[1, 2, 3, 4, 5], pd.date_range("2015-01-01", freq="W", periods=5)],
     ....:        names=["v", "d"],
     ....:    ),
     ....: )
     ....: 
    
    In [69]: df
    Out[69]: 
     date  a
    v d 
    1 2015-01-04 2015-01-04  0
    2 2015-01-11 2015-01-11  1
    3 2015-01-18 2015-01-18  2
    4 2015-01-25 2015-01-25  3
    5 2015-02-01 2015-02-01  4
    
    [5 rows x 2 columns] 
    
    In [74]: df.resample("M", on="date")[["a"]].sum()
    Out[74]:
     a
    date
    2015-01-31  6
    2015-02-28  4
    
    [2 rows x 1 columns]
    
    In [75]: df.resample("M", level="d")[["a"]].sum()
    Out[75]:
     a
    d
    2015-01-31  6
    2015-02-28  4
    
    [2 rows x 1 columns] 
    
  • GbqConnector 的 .get_credentials() 方法现在可以首先尝试获取 应用程序默认凭据。有关更多详细信息,请参阅文档 (GH 13577)。

  • DatetimeIndex 和 Timestamp 的 .tz_localize() 方法现在具有 errors 关键字,因此您可以将不存在的时间戳可能强制转换为 NaT。默认行为仍然是引发 NonExistentTimeError (GH 13057)。

  • .to_hdf/read_hdf() 现在接受路径对象(例如 pathlib.Path、py.path.local)作为文件路径 (GH 11773)。

  • 使用 engine='python' 的 pd.read_csv() 现在支持 decimal (GH 12933)、na_filter (GH 13321) 以及 memory_map 选项。

  • 与 Python API 一致,pd.read_csv() 现在会将 +inf 解释为正无穷 (GH 13274)。

  • pd.read_html() 现在支持 na_values、converters、keep_default_na 选项 (GH 13461)。

  • Categorical.astype() 现在接受一个可选的布尔参数 copy,当 dtype 是 categorical 时有效 (GH 13209)。

  • DataFrame 现在具有 .asof() 方法,根据所选子集返回最后一个非 NaN 值 (GH 13358)。

  • 如果传入的是 OrderedDict 对象列表,则 DataFrame 构造函数现在会遵循键排序 (GH 13304)。

  • pd.read_html() 现在支持 decimal 选项 (GH 12907)。

  • Series 现在具有 .is_monotonic、.is_monotonic_increasing、.is_monotonic_decreasing 属性,类似于 Index (GH 13336)。

  • DataFrame.to_sql() 现在允许将单个值作为所有列的 SQL 类型 (GH 11886)。

  • Series.append 现在支持 ignore_index 选项 (GH 13677)。

  • .to_stata() 和 StataWriter 现在可以使用字典将列名转换为标签,将变量标签写入 Stata dta 文件 (GH 13535, GH 13536)。

  • .to_stata() 和 StataWriter 现在会自动将 datetime64[ns] 列转换为 Stata 格式 %tc,而不是引发 ValueError (GH 12259)

  • 当 convert_categoricals=True 时,read_stata() 和 StataReader 在读取具有重复值标签的 Stata 文件时引发更明确的错误消息 (GH 13923)

  • DataFrame.style 现在会渲染稀疏的 MultiIndexes (GH 11655)

  • DataFrame.style 现在会显示列级别的名称(例如 DataFrame.columns.names)(GH 13775)

  • DataFrame 已支持根据行中的值重新排序列使用 df.sort_values(by='...', axis=1) (GH 10806)

    In [70]: df = pd.DataFrame({"A": [2, 7], "B": [3, 5], "C": [4, 8]}, index=["row1", "row2"])
    
    In [71]: df
    Out[71]: 
     A  B  C
    row1  2  3  4
    row2  7  5  8
    
    [2 rows x 3 columns]
    
    In [72]: df.sort_values(by="row2", axis=1)
    Out[72]: 
     B  A  C
    row1  3  2  4
    row2  5  7  8
    
    [2 rows x 3 columns] 
    
  • 添加了关于读取具有混合数据类型的列以及如何处理的文档信息 I/O (GH 13746)

  • to_html() 现在具有 border 参数来控制开放的 <table> 标签中的值。默认值是 html.border 选项的值,默认为 1。这也会影响笔记本的 HTML 表示,但由于 Jupyter 的 CSS 包含一个 border-width 属性,视觉效果是相同的。(GH 11563).

  • 在使用连接字符串时,sql 函数将在未安装 sqlalchemy 时引发 ImportError (GH 11920).

  • 与 matplotlib 2.0 的兼容性。旧版本的 pandas 也应该与 matplotlib 2.0 兼容 (GH 13333)

  • Timestamp、Period、DatetimeIndex、PeriodIndex 和 .dt 访问器现在具有 .is_leap_year 属性,用于检查日期是否属于闰年。(GH 13727)

  • astype() 现在将接受一个列名到数据类型映射的字典作为 dtype 参数。(GH 12086)

  • pd.read_json 和 DataFrame.to_json 现在已支持使用 lines 选项读取和写入 json 行,请参阅 Line delimited json (GH 9180)

  • read_excel() 现在支持 true_values 和 false_values 关键字参数 (GH 13347)

  • groupby() 现在将接受一个标量和一个单元素列表来指定非 MultiIndex 分组器上的 level。(GH 13907)

  • 在 Excel 日期列中存在不可转换的日期时,将返回未转换的日期,并且列将是 object 类型,而不是引发异常 (GH 10001)。

  • pd.Timedelta(None) 现在被接受,并将返回 NaT,与 pd.Timestamp 相同 (GH 13687)

  • pd.read_stata() 现在可以处理一些格式为 111 的文件,这些文件是由 SAS 生成 Stata dta 文件时产生的 (GH 11526)

  • Series 和 Index 现在支持 divmod,将返回一个系列或索引的元组。这与广播规则相关的标准二元运算符的行为相同 (GH 14208)。 ## API 变更

Series.tolist() 现在会返回 Python 类型

Series.tolist() 现在会返回 Python 类型的输出,模仿 NumPy 的 .tolist() 行为 (GH 10904)

In [73]: s = pd.Series([1, 2, 3]) 

先前行为:

In [7]: type(s.tolist()[0])
Out[7]:
 <class 'numpy.int64'> 

新行为:

In [74]: type(s.tolist()[0])
Out[74]: int 

不同索引的 Series 运算符

以下 Series 运算符已更改,以使所有运算符保持一致,包括 DataFrame (GH 1134, GH 4581, GH 13538)

  • 当 index 不同时,Series 比较运算符现在会引发 ValueError。

  • Series 逻辑运算符会对齐左右两侧的 index。

警告

直到 0.18.1 版本,比较具有相同长度的 Series,即使 .index 不同也会成功(结果忽略 .index)。从 0.19.0 版本开始,这将引发 ValueError 以更加严格。本节还描述了如何保留先前行为或对齐不同索引,使用像 .eq 这样的灵活比较方法。

因此,Series 和 DataFrame 运算符的行为如下:

算术运算符

算术运算符会对齐 index(无更改)。

In [75]: s1 = pd.Series([1, 2, 3], index=list("ABC"))

In [76]: s2 = pd.Series([2, 2, 2], index=list("ABD"))

In [77]: s1 + s2
Out[77]: 
A    3.0
B    4.0
C    NaN
D    NaN
Length: 4, dtype: float64

In [78]: df1 = pd.DataFrame([1, 2, 3], index=list("ABC"))

In [79]: df2 = pd.DataFrame([2, 2, 2], index=list("ABD"))

In [80]: df1 + df2
Out[80]: 
 0
A  3.0
B  4.0
C  NaN
D  NaN

[4 rows x 1 columns] 

比较运算符

当 .index 不同时,比较运算符会引发 ValueError。

先前行为 (Series):

Series 比较值会忽略 .index,只要两者长度相同:

In [1]: s1 == s2
Out[1]:
A    False
B     True
C    False
dtype: bool 

新行为 (Series):

In [2]: s1 == s2
Out[2]:
ValueError: Can only compare identically-labeled Series objects 

注意

要实现与以前版本相同的结果(基于位置比较值,忽略 .index),请比较 .values。

In [81]: s1.values == s2.values
Out[81]: array([False,  True, False]) 

如果要比较 Series 并对齐其 .index,请参见下面的灵活比较方法部分:

In [82]: s1.eq(s2)
Out[82]: 
A    False
B     True
C    False
D    False
Length: 4, dtype: bool 

当前行为 (DataFrame,无变化):

In [3]: df1 == df2
Out[3]:
ValueError: Can only compare identically-labeled DataFrame objects 

逻辑运算符

逻辑运算符会对齐左右两侧的 .index。

先前行为 (Series),仅保留左侧 index:

In [4]: s1 = pd.Series([True, False, True], index=list('ABC'))
In [5]: s2 = pd.Series([True, True, True], index=list('ABD'))
In [6]: s1 & s2
Out[6]:
A     True
B    False
C    False
dtype: bool 

新行为 (Series):

In [83]: s1 = pd.Series([True, False, True], index=list("ABC"))

In [84]: s2 = pd.Series([True, True, True], index=list("ABD"))

In [85]: s1 & s2
Out[85]: 
A     True
B    False
C    False
D    False
Length: 4, dtype: bool 

注意

Series 逻辑运算符将 NaN 结果填充为 False。

注意

要实现与以前版本相同的结果(仅基于左侧索引比较值),您可以使用 reindex_like:

In [86]: s1 & s2.reindex_like(s1)
Out[86]: 
A     True
B    False
C    False
Length: 3, dtype: bool 

当前行为 (DataFrame,无变化):

In [87]: df1 = pd.DataFrame([True, False, True], index=list("ABC"))

In [88]: df2 = pd.DataFrame([True, True, True], index=list("ABD"))

In [89]: df1 & df2
Out[89]: 
 0
A   True
B  False
C  False
D  False

[4 rows x 1 columns] 

灵活比较方法

Series 灵活的比较方法如 eq、ne、le、lt、ge 和 gt 现在会对齐两个 index。如果要比较具有不同 index 的两个 Series,请使用这些运算符。

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

In [91]: s2 = pd.Series([2, 2, 2], index=["b", "c", "d"])

In [92]: s1.eq(s2)
Out[92]: 
a    False
b     True
c    False
d    False
Length: 4, dtype: bool

In [93]: s1.ge(s2)
Out[93]: 
a    False
b     True
c     True
d    False
Length: 4, dtype: bool 

以前,这与比较运算符的行为相同(见上文)。### Series 类型的赋值推广

当 Series 与不兼容值进行赋值时,现在将正确推广其 dtype 到当前 dtype (GH 13234)

In [94]: s = pd.Series() 

先前行为:

In [2]: s["a"] = pd.Timestamp("2016-01-01")

In [3]: s["b"] = 3.0
TypeError: invalid type promotion 

新行为:

In [95]: s["a"] = pd.Timestamp("2016-01-01")

In [96]: s["b"] = 3.0

In [97]: s
Out[97]: 
a    2016-01-01 00:00:00
b                    3.0
Length: 2, dtype: object

In [98]: s.dtype
Out[98]: dtype('O') 
``` ### 函数 `.to_datetime()` 变更

以前,如果 `.to_datetime()` 遇到混合的整数/浮点数和字符串,但没有日期时间且 `errors='coerce'`,它会将所有内容转换为 `NaT`。

**先前行为**:

```py
In [2]: pd.to_datetime([1, 'foo'], errors='coerce')
Out[2]: DatetimeIndex(['NaT', 'NaT'], dtype='datetime64[ns]', freq=None) 

当前行为:

现在将整数/浮点数转换为默认单位 ns。

In [99]: pd.to_datetime([1, "foo"], errors="coerce")
Out[99]: DatetimeIndex(['1970-01-01 00:00:00.000000001', 'NaT'], dtype='datetime64[ns]', freq=None) 

与 .to_datetime() 相关的 Bug 修复:

  • 在传递整数或浮点数时,以及没有 unit 和 errors='coerce' 时,pd.to_datetime() 中存在错误 (GH 13180)。

  • pd.to_datetime() 在传递无效数据类型(例如布尔值)时存在错误;现在将遵守 errors 关键字 (GH 13176)

  • 在 pd.to_datetime() 中存在 Bug,当 int8 和 int16 dtypes 溢出时 (GH 13451)

  • 在 pd.to_datetime() 中存在 Bug,在 errors='ignore' 时引发 AttributeError,并且另一个字符串无效时 (GH 12424)

  • 当指定 unit 时,pd.to_datetime() 中的 Bug 未正确转换浮点数,导致截断的日期时间 (GH 13834) ### 合并变更

合并现在将保留连接键的 dtype (GH 8596)

In [100]: df1 = pd.DataFrame({"key": [1], "v1": [10]})

In [101]: df1
Out[101]: 
 key  v1
0    1  10

[1 rows x 2 columns]

In [102]: df2 = pd.DataFrame({"key": [1, 2], "v1": [20, 30]})

In [103]: df2
Out[103]: 
 key  v1
0    1  20
1    2  30

[2 rows x 2 columns] 

先前行为:

In [5]: pd.merge(df1, df2, how='outer')
Out[5]:
 key    v1
0  1.0  10.0
1  1.0  20.0
2  2.0  30.0

In [6]: pd.merge(df1, df2, how='outer').dtypes
Out[6]:
key    float64
v1     float64
dtype: object 

新行为:

我们能够保留连接键

In [104]: pd.merge(df1, df2, how="outer")
Out[104]: 
 key  v1
0    1  10
1    1  20
2    2  30

[3 rows x 2 columns]

In [105]: pd.merge(df1, df2, how="outer").dtypes
Out[105]: 
key    int64
v1     int64
Length: 2, dtype: object 

当然,如果引入了缺失值,那么结果的 dtype 将被提升,这与以前相同。

In [106]: pd.merge(df1, df2, how="outer", on="key")
Out[106]: 
 key  v1_x  v1_y
0    1  10.0    20
1    2   NaN    30

[2 rows x 3 columns]

In [107]: pd.merge(df1, df2, how="outer", on="key").dtypes
Out[107]: 
key       int64
v1_x    float64
v1_y      int64
Length: 3, dtype: object 
``` ### 方法 `.describe()` 变更

在 `.describe()` 输出的索引中的百分位数标识符现在将四舍五入为保持它们不同的最小精度 ([GH 13104](https://github.com/pandas-dev/pandas/issues/13104))

```py
In [108]: s = pd.Series([0, 1, 2, 3, 4])

In [109]: df = pd.DataFrame([0, 1, 2, 3, 4]) 

先前行为:

百分位数最多四舍五入到一位小数点,如果数据框中的百分位数重复,可能会引发 ValueError。

In [3]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[3]:
count     5.000000
mean      2.000000
std       1.581139
min       0.000000
0.0%      0.000400
0.1%      0.002000
0.1%      0.004000
50%       2.000000
99.9%     3.996000
100.0%    3.998000
100.0%    3.999600
max       4.000000
dtype: float64

In [4]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[4]:
...
ValueError: cannot reindex from a duplicate axis 

新行为:

In [110]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[110]: 
count     5.000000
mean      2.000000
std       1.581139
min       0.000000
0.01%     0.000400
0.05%     0.002000
0.1%      0.004000
50%       2.000000
99.9%     3.996000
99.95%    3.998000
99.99%    3.999600
max       4.000000
Length: 12, dtype: float64

In [111]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[111]: 
 0
count   5.000000
mean    2.000000
std     1.581139
min     0.000000
0.01%   0.000400
0.05%   0.002000
0.1%    0.004000
50%     2.000000
99.9%   3.996000
99.95%  3.998000
99.99%  3.999600
max     4.000000

[12 rows x 1 columns] 

此外:

  • 传递重复的 percentiles 现在会引发 ValueError。

  • 在具有混合类型列索引的 DataFrame 上调用 .describe() 时存在 Bug,以前会引发 TypeError (GH 13288) ### Period 变更

现在 PeriodIndex 具有 period dtype

PeriodIndex现在有自己的period dtype。period dtype 是一种类似于category或时区感知 dtype(datetime64[ns, tz])的 pandas 扩展 dtype (GH 13941)。由于这个变化的结果,PeriodIndex不再具有整数 dtype:

之前的行为:

In [1]: pi = pd.PeriodIndex(['2016-08-01'], freq='D')

In [2]: pi
Out[2]: PeriodIndex(['2016-08-01'], dtype='int64', freq='D')

In [3]: pd.api.types.is_integer_dtype(pi)
Out[3]: True

In [4]: pi.dtype
Out[4]: dtype('int64') 

新行为:

In [112]: pi = pd.PeriodIndex(["2016-08-01"], freq="D")

In [113]: pi
Out[113]: PeriodIndex(['2016-08-01'], dtype='period[D]')

In [114]: pd.api.types.is_integer_dtype(pi)
Out[114]: False

In [115]: pd.api.types.is_period_dtype(pi)
Out[115]: True

In [116]: pi.dtype
Out[116]: period[D]

In [117]: type(pi.dtype)
Out[117]: pandas.core.dtypes.dtypes.PeriodDtype 

Period('NaT') 现在返回 pd.NaT

以前,Period有自己的Period('NaT')表示,与pd.NaT不同。现在Period('NaT')已更改为返回pd.NaT。(GH 12759,GH 13582)

之前的行为:

In [5]: pd.Period('NaT', freq='D')
Out[5]: Period('NaT', 'D') 

新行为:

这些导致 pd.NaT 而不提供 freq 选项。

In [118]: pd.Period("NaT")
Out[118]: NaT

In [119]: pd.Period(None)
Out[119]: NaT 

为了与Period的加法和减法兼容,pd.NaT现在支持与int的加法和减法。以前会引发ValueError。

之前的行为:

In [5]: pd.NaT + 1
...
ValueError: Cannot add integral value to Timestamp without freq. 

新行为:

In [120]: pd.NaT + 1
Out[120]: NaT

In [121]: pd.NaT - 1
Out[121]: NaT 

PeriodIndex.values 现在返回 Period 对象的数组

.values 已更改为返回Period对象的数组,而不是整数数组 (GH 13988)。

之前的行为:

In [6]: pi = pd.PeriodIndex(['2011-01', '2011-02'], freq='M')
In [7]: pi.values
Out[7]: array([492, 493]) 

新行为:

In [122]: pi = pd.PeriodIndex(["2011-01", "2011-02"], freq="M")

In [123]: pi.values
Out[123]: array([Period('2011-01', 'M'), Period('2011-02', 'M')], dtype=object) 
```  ### 索引 `+` / `-` 不再用于集合操作

对于基本的索引类型和 DatetimeIndex(不是数值索引类型)的加法和减法,以前执行的是集合操作(集合并和差)。此行为自 0.15.0 版本起已经被弃用(推荐使用特定的`.union()`和`.difference()`方法),现在已被禁用。现在尽可能使用`+`和`-`进行逐元素操作,例如连接字符串或减去日期时间([GH 8227](https://github.com/pandas-dev/pandas/issues/8227),[GH 14127](https://github.com/pandas-dev/pandas/issues/14127))。

之前的行为:

```py
In [1]: pd.Index(['a', 'b']) + pd.Index(['a', 'c'])
FutureWarning: using '+' to provide set union with Indexes is deprecated, use '|' or .union()
Out[1]: Index(['a', 'b', 'c'], dtype='object') 

新行为:同样的操作现在将执行逐元素加法:

In [124]: pd.Index(["a", "b"]) + pd.Index(["a", "c"])
Out[124]: Index(['aa', 'bc'], dtype='object') 

请注意,数值索引对象已经执行了逐元素操作。例如,两个整数索引相加的行为不变。基本的 Index 现在与此行为保持一致。

In [125]: pd.Index([1, 2, 3]) + pd.Index([2, 3, 4])
Out[125]: Index([3, 5, 7], dtype='int64') 

此外,由于这个变化,现在可以减去两个 DatetimeIndex 对象,结果为 TimedeltaIndex:

之前的行为:

In [1]: (pd.DatetimeIndex(['2016-01-01', '2016-01-02'])
 ...: - pd.DatetimeIndex(['2016-01-02', '2016-01-03']))
FutureWarning: using '-' to provide set differences with datetimelike Indexes is deprecated, use .difference()
Out[1]: DatetimeIndex(['2016-01-01'], dtype='datetime64[ns]', freq=None) 

新行为:

In [126]: (
 .....:    pd.DatetimeIndex(["2016-01-01", "2016-01-02"])
 .....:    - pd.DatetimeIndex(["2016-01-02", "2016-01-03"])
 .....: )
 .....: 
Out[126]: TimedeltaIndex(['-1 days', '-1 days'], dtype='timedelta64[ns]', freq=None) 
```  ### `Index.difference` 和 `.symmetric_difference` 更改

`Index.difference` 和 `Index.symmetric_difference` 现在将更一致地将 `NaN` 值视为任何其他值。 ([GH 13514](https://github.com/pandas-dev/pandas/issues/13514))

```py
In [127]: idx1 = pd.Index([1, 2, 3, np.nan])

In [128]: idx2 = pd.Index([0, 1, np.nan]) 

之前的行为:

In [3]: idx1.difference(idx2)
Out[3]: Float64Index([nan, 2.0, 3.0], dtype='float64')

In [4]: idx1.symmetric_difference(idx2)
Out[4]: Float64Index([0.0, nan, 2.0, 3.0], dtype='float64') 

新行为:

In [129]: idx1.difference(idx2)
Out[129]: Index([2.0, 3.0], dtype='float64')

In [130]: idx1.symmetric_difference(idx2)
Out[130]: Index([0.0, 2.0, 3.0], dtype='float64') 
```  ### `Index.unique` 一致地返回 `Index`

`Index.unique()` 现在返回适当 `dtype` 的唯一值作为 `Index`。([GH 13395](https://github.com/pandas-dev/pandas/issues/13395))。以前,大多数 `Index` 类返回 `np.ndarray`,而 `DatetimeIndex`、`TimedeltaIndex` 和 `PeriodIndex` 返回 `Index` 来保留元数据,如时区。

**之前的行为**:

```py
In [1]: pd.Index([1, 2, 3]).unique()
Out[1]: array([1, 2, 3])

In [2]: pd.DatetimeIndex(['2011-01-01', '2011-01-02',
 ...:                  '2011-01-03'], tz='Asia/Tokyo').unique()
Out[2]:
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
 '2011-01-03 00:00:00+09:00'],
 dtype='datetime64[ns, Asia/Tokyo]', freq=None) 

新行为:

In [131]: pd.Index([1, 2, 3]).unique()
Out[131]: Index([1, 2, 3], dtype='int64')

In [132]: pd.DatetimeIndex(
 .....:    ["2011-01-01", "2011-01-02", "2011-01-03"], tz="Asia/Tokyo"
 .....: ).unique()
 .....: 
Out[132]: 
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
 '2011-01-03 00:00:00+09:00'],
 dtype='datetime64[ns, Asia/Tokyo]', freq=None) 
```  ### `MultiIndex` 构造函数、`groupby` 和 `set_index` 保留分类 `dtype`

`MultiIndex.from_arrays` 和 `MultiIndex.from_product` 现在会在 `MultiIndex` 级别中保留分类 dtype ([GH 13743](https://github.com/pandas-dev/pandas/issues/13743), [GH 13854](https://github.com/pandas-dev/pandas/issues/13854))。

```py
In [133]: cat = pd.Categorical(["a", "b"], categories=list("bac"))

In [134]: lvl1 = ["foo", "bar"]

In [135]: midx = pd.MultiIndex.from_arrays([cat, lvl1])

In [136]: midx
Out[136]: 
MultiIndex([('a', 'foo'),
 ('b', 'bar')],
 ) 

之前的行为:

In [4]: midx.levels[0]
Out[4]: Index(['b', 'a', 'c'], dtype='object')

In [5]: midx.get_level_values[0]
Out[5]: Index(['a', 'b'], dtype='object') 

新行为:单个级别现在是 CategoricalIndex:

In [137]: midx.levels[0]
Out[137]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category')

In [138]: midx.get_level_values(0)
Out[138]: CategoricalIndex(['a', 'b'], categories=['b', 'a', 'c'], ordered=False, dtype='category') 

MultiIndex.from_product 也进行了类似的更改。因此,groupby 和 set_index 也会保留索引中的分类 dtype。

In [139]: df = pd.DataFrame({"A": [0, 1], "B": [10, 11], "C": cat})

In [140]: df_grouped = df.groupby(by=["A", "C"], observed=False).first()

In [141]: df_set_idx = df.set_index(["A", "C"]) 

之前的行为:

In [11]: df_grouped.index.levels[1]
Out[11]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [12]: df_grouped.reset_index().dtypes
Out[12]:
A      int64
C     object
B    float64
dtype: object

In [13]: df_set_idx.index.levels[1]
Out[13]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [14]: df_set_idx.reset_index().dtypes
Out[14]:
A      int64
C     object
B      int64
dtype: object 

新行为:

In [142]: df_grouped.index.levels[1]
Out[142]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')

In [143]: df_grouped.reset_index().dtypes
Out[143]: 
A       int64
C    category
B     float64
Length: 3, dtype: object

In [144]: df_set_idx.index.levels[1]
Out[144]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')

In [145]: df_set_idx.reset_index().dtypes
Out[145]: 
A       int64
C    category
B       int64
Length: 3, dtype: object 
```  ### 函数 `read_csv` 将逐步枚举块

当使用 `chunksize=n` 调用 `read_csv()` 时,如果不指定索引,每个块以前都会有一个独立生成的索引,从 `0` 到 `n-1`。现在,它们分别被赋予一个递进的索引,从第一个块的 `0` 开始,从第二个块的 `n` 开始,以此类推,这样,当连接时,它们与使用 `read_csv()` 调用时的结果相同,而不带 `chunksize=` 参数 ([GH 12185](https://github.com/pandas-dev/pandas/issues/12185))。

```py
In [146]: data = "A,B\n0,1\n2,3\n4,5\n6,7" 

之前的行为:

In [2]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[2]:
 A  B
0  0  1
1  2  3
0  4  5
1  6  7 

新行为:

In [147]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[147]: 
 A  B
0  0  1
1  2  3
2  4  5
3  6  7

[4 rows x 2 columns] 
```  ### 稀疏数据变更

这些更改使 pandas 能够处理更多的稀疏数据 `dtype`,并且使数据处理的体验更加流畅。

#### `int64` 和 `bool` 类型支持增强

稀疏数据结构现在增强了对 `int64` 和 `bool` `dtype` 的支持 ([GH 667](https://github.com/pandas-dev/pandas/issues/667), [GH 13849](https://github.com/pandas-dev/pandas/issues/13849))。

以前,默认情况下稀疏数据为 `float64` dtype,即使所有输入都是 `int` 或 `bool` dtype。您必须显式指定 `dtype` 来创建具有 `int64` dtype 的稀疏数据。此外,必须显式指定 `fill_value`,因为默认值为 `np.nan`,而 `int64` 或 `bool` 数据中不包含它。

```py
In [1]: pd.SparseArray([1, 2, 0, 0])
Out[1]:
[1.0, 2.0, 0.0, 0.0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

# specifying int64 dtype, but all values are stored in sp_values because
# fill_value default is np.nan
In [2]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[2]:
[1, 2, 0, 0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

In [3]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64, fill_value=0)
Out[3]:
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32) 

从 v0.19.0 开始,稀疏数据保持输入 dtype,并使用更合适的 fill_value 默认值(int64 dtype 为 0,bool dtype 为 False)。

In [148]: pd.arrays.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[148]: 
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32)

In [149]: pd.arrays.SparseArray([True, False, False, False])
Out[149]: 
[True, False, False, False]
Fill: False
IntIndex
Indices: array([0], dtype=int32) 

更多详细信息,请参阅文档。

运算符现在保留 dtype

  • 稀疏数据结构现在可以在算术操作后保留 dtype (GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype

s + 1 
  • 现在稀疏数据结构支持 astype 来转换内部 dtype (GH 13900)
s = pd.SparseSeries([1.0, 0.0, 2.0, 0.0], fill_value=0)
s
s.astype(np.int64) 

如果数据包含无法转换为指定 dtype 的值,则 astype 会失败。请注意,此限制适用于默认为 np.nan 的 fill_value。

In [7]: pd.SparseSeries([1., np.nan, 2., np.nan], fill_value=np.nan).astype(np.int64)
Out[7]:
ValueError: unable to coerce current fill_value nan to int64 dtype 

其他稀疏修复

  • 子类化的 SparseDataFrame 和 SparseSeries 现在在切片或转置时保留类类型。(GH 13787)

  • SparseArray 的 bool 类型现在支持逻辑(bool)运算符(GH 14000)

  • 带有 MultiIndex 的 SparseSeries 中 [] 索引可能会引发 IndexError 的 bug(GH 13144)

  • 带有 MultiIndex 的 SparseSeries 中 [] 索引的结果可能具有正常的 Index 的 bug(GH 13144)

  • SparseDataFrame 中的一个 bug,axis=None 没有默认为 axis=0(GH 13048)

  • 使用 object dtype 创建 SparseSeries 和 SparseDataFrame 可能会引发 TypeError 的 bug(GH 11633)

  • SparseDataFrame 中的一个 bug,不遵守传递的 SparseArray 或 SparseSeries 的 dtype 和 fill_value(GH 13866)

  • SparseArray 和 SparseSeries 中不将 ufunc 应用于 fill_value 的 bug(GH 13853)

  • SparseSeries.abs 中的一个 bug,错误地保留了负的 fill_value(GH 13853)

  • 在多类型 SparseDataFrame 上进行单行切片的 bug,之前类型被强制转换为浮点数(GH 13917)

  • SparseSeries 切片中的一个 bug,将整数类型转换为浮点数(GH 8292)

  • SparseDataFarme 中比较操作可能会引发 TypeError 的 bug(GH 13001)

  • SparseDataFarme.isnull 中引发 ValueError 的 bug(GH 8276)

  • 带有 bool dtype 的 SparseSeries 表示可能会引发 IndexError 的 bug(GH 13110)

  • bool 或 int64 dtype 的 SparseSeries 和 SparseDataFrame 中可能会显示其值为 float64 dtype 的 bug(GH 13110)

  • 使用 bool dtype 的 SparseArray 进行稀疏索引可能返回不正确的结果的 bug(GH 13985)

  • 从 SparseSeries 创建的 SparseArray 可能会丢失 dtype 的 bug(GH 13999)

  • SparseSeries 与密集数据比较返回正常的 Series 而不是 SparseSeries 的 bug([GH 13999]( https://github.com/pandas-dev/pandas/issues/13999 )### 索引器 dtype 更改

注意

此更改仅影响在 Windows 上运行的 64 位 python,并且仅影响相对高级的索引操作

Index.get_indexer 等返回索引器数组的方法会将该数组强制转换为“平台整数”,以便可以直接在第三方库操作中使用,如 numpy.take。以前,平台整数被定义为 np.int_,它对应于 C 整数,但正确的类型,现在使用的是 np.intp,它对应于可以容纳指针的 C 整数大小(GH 3033,GH 13972)。

这些类型在许多平台上是相同的,但对于 Windows 上的 64 位 Python,np.int_ 是 32 位,而 np.intp 是 64 位。更改此行为可以提高该平台上许多操作的性能。

以前的行为:

In [1]: i = pd.Index(['a', 'b', 'c'])

In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int32') 

新行为:

In [1]: i = pd.Index(['a', 'b', 'c'])

In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int64') 
```  ### 其他 API 更改

+   如果 `Timestamp.to_pydatetime` 的 `warn=True`,并且实例具有非零纳秒数,则会发出 `UserWarning` 警告,以前会在标准输出中打印消息([GH 14101](https://github.com/pandas-dev/pandas/issues/14101))。

+   `Series.unique()` 对于日期时间和时区现在返回带有时区的 `Timestamp` 数组([GH 13565](https://github.com/pandas-dev/pandas/issues/13565))。

+   调用 `Panel.to_sparse()` 时将引发 `NotImplementedError` 异常([GH 13778](https://github.com/pandas-dev/pandas/issues/13778))。

+   调用 `Index.reshape()` 时将引发 `NotImplementedError` 异常([GH 12882](https://github.com/pandas-dev/pandas/issues/12882))。

+   `.filter()` 强制互斥关键字参数([GH 12399](https://github.com/pandas-dev/pandas/issues/12399))。

+   `eval` 的 `float32` 类型的升级规则已更新,以使其更符合 NumPy 的规则。如果将 pandas 的 `float32` 对象乘以标量 `float64`,则新行为不会升级为 `float64`([GH 12388](https://github.com/pandas-dev/pandas/issues/12388))。

+   如果在 groupby 或 resample 对象上调用 NumPy ufuncs 如 `np.mean`,则会引发 `UnsupportedFunctionCall` 错误([GH 12811](https://github.com/pandas-dev/pandas/issues/12811))。

+   `__setitem__` 将不再将可调用的 rhs 应用为函数而不是存储它。直接调用 `where` 以获得以前的行为([GH 13299](https://github.com/pandas-dev/pandas/issues/13299))。

+   对 `.sample()` 的调用将尊重通过 `numpy.random.seed(n)` 设置的随机种子([GH 13161](https://github.com/pandas-dev/pandas/issues/13161))

+   `Styler.apply` 对于你的函数必须返回的输出现在更加严格。对于 `axis=0` 或 `axis=1`,输出形状必须相同。对于 `axis=None`,输出必须是具有相同列和索引标签的 DataFrame([GH 13222](https://github.com/pandas-dev/pandas/issues/13222))。

+   `Float64Index.astype(int)` 现在会在 `Float64Index` 包含 `NaN` 值时引发 `ValueError`([GH 13149](https://github.com/pandas-dev/pandas/issues/13149))

+   `TimedeltaIndex.astype(int)`和`DatetimeIndex.astype(int)`现在将返回`Int64Index`而不是`np.array`([GH 13209](https://github.com/pandas-dev/pandas/issues/13209))

+   将多频率传递给正常的`Index`现在返回具有`object`数据类型的`Index`([GH 13664](https://github.com/pandas-dev/pandas/issues/13664))

+   使用`Period`的`PeriodIndex.fillna`现在强制转换为`object`数据类型([GH 13664](https://github.com/pandas-dev/pandas/issues/13664))

+   从`DataFrame.boxplot(by=col)`生成的分面箱线图现在在`return_type`不为 None 时返回一个`Series`。以前这些返回一个`OrderedDict`。请注意,当`return_type=None`时,默认情况下,这些仍然返回一个 2-D NumPy 数组([GH 12216](https://github.com/pandas-dev/pandas/issues/12216), [GH 7096](https://github.com/pandas-dev/pandas/issues/7096)).

+   如果提供的模式不是`r`、`r+`和`a`,`pd.read_hdf`现在将引发`ValueError`而不是`KeyError`。([GH 13623](https://github.com/pandas-dev/pandas/issues/13623))

+   当在不存在的文件上调用`pd.read_csv()`、`pd.read_table()`和`pd.read_hdf()`时,Python 3.x 现在会引发内置的`FileNotFoundError`异常;这在 Python 2.x 中被回退为`IOError`([GH 14086](https://github.com/pandas-dev/pandas/issues/14086))

+   更具信息性的异常将通过 csv 解析器传递。异常类型现在将是原始异常类型,而不是`CParserError`([GH 13652](https://github.com/pandas-dev/pandas/issues/13652)).

+   在 C 引擎中,`pd.read_csv()`现在在`sep`编码超过一个字符长时会发出`ParserWarning`或引发`ValueError`([GH 14065](https://github.com/pandas-dev/pandas/issues/14065))

+   `DataFrame.values`现在将返回`float64`,其中包含混合`int64`和`uint64`数据类型的`DataFrame`,符合`np.find_common_type`([GH 10364](https://github.com/pandas-dev/pandas/issues/10364), [GH 13917](https://github.com/pandas-dev/pandas/issues/13917))

+   `.groupby.groups`现在将返回`Index`对象的字典,而不是`np.ndarray`或`lists`的字典([GH 14293](https://github.com/pandas-dev/pandas/issues/14293))  ## 弃用

+   `Series.reshape`和`Categorical.reshape`已被弃用,并将在随后的版本中移除([GH 12882](https://github.com/pandas-dev/pandas/issues/12882), [GH 12882](https://github.com/pandas-dev/pandas/issues/12882))

+   `PeriodIndex.to_datetime`已被弃用,推荐使用`PeriodIndex.to_timestamp`([GH 8254](https://github.com/pandas-dev/pandas/issues/8254))

+   `Timestamp.to_datetime`已被弃用,推荐使用`Timestamp.to_pydatetime`([GH 8254](https://github.com/pandas-dev/pandas/issues/8254))

+   `Index.to_datetime`和`DatetimeIndex.to_datetime`已被弃用,推荐使用`pd.to_datetime`([GH 8254](https://github.com/pandas-dev/pandas/issues/8254))

+   `pandas.core.datetools` 模块已被弃用,并将在随后的版本中移除 ([GH 14094](https://github.com/pandas-dev/pandas/issues/14094))

+   `SparseList` 已被弃用,并将在将来的版本中移除 ([GH 13784](https://github.com/pandas-dev/pandas/issues/13784))

+   `DataFrame.to_html()` 和 `DataFrame.to_latex()` 已经移除了 `colSpace` 参数,改用 `col_space` ([GH 13857](https://github.com/pandas-dev/pandas/issues/13857))

+   `DataFrame.to_sql()` 已经弃用 `flavor` 参数,因为在未安装 SQLAlchemy 时它是多余的 ([GH 13611](https://github.com/pandas-dev/pandas/issues/13611))

+   弃用的 `read_csv` 关键词:

    +   `compact_ints` 和 `use_unsigned` 已被弃用,并将在将来的版本中移除 ([GH 13320](https://github.com/pandas-dev/pandas/issues/13320))

    +   `buffer_lines` 已被弃用,并将在将来的版本中移除 ([GH 13360](https://github.com/pandas-dev/pandas/issues/13360))

    +   `as_recarray` 已经被弃用,并将在将来的版本中移除 ([GH 13373](https://github.com/pandas-dev/pandas/issues/13373))

    +   `skip_footer` 已被弃用,推荐使用 `skipfooter`,并将在将来的版本中移除 ([GH 13349](https://github.com/pandas-dev/pandas/issues/13349))

+   顶层 `pd.ordered_merge()` 已重命名为 `pd.merge_ordered()`,原始名称将在将来的版本中移除 ([GH 13358](https://github.com/pandas-dev/pandas/issues/13358))

+   `Timestamp.offset` 属性(以及构造函数中的命名参数)已被弃用,推荐使用 `freq` ([GH 12160](https://github.com/pandas-dev/pandas/issues/12160))

+   `pd.tseries.util.pivot_annual` 已被弃用。使用 `pivot_table` 作为替代方法,一个示例在这里 ([GH 736](https://github.com/pandas-dev/pandas/issues/736))

+   `pd.tseries.util.isleapyear` 已被弃用,并将在随后的版本中移除。Datetime-likes 现在具有 `.is_leap_year` 属性 ([GH 13727](https://github.com/pandas-dev/pandas/issues/13727))

+   `Panel4D` 和 `PanelND` 构造函数已被弃用,并将在将来的版本中移除。推荐的表示这些类型的 n-维数据的方法是使用 [xarray 包](http://xarray.pydata.org/en/stable/)。pandas 提供了 `to_xarray()` 方法来自动执行此转换 ([GH 13564](https://github.com/pandas-dev/pandas/issues/13564))。

+   `pandas.tseries.frequencies.get_standard_freq` 已被弃用。使用 `pandas.tseries.frequencies.to_offset(freq).rule_code` 代替 ([GH 13874](https://github.com/pandas-dev/pandas/issues/13874))

+   `pandas.tseries.frequencies.to_offset` 的 `freqstr` 关键词已被弃用,改用 `freq` ([GH 13874](https://github.com/pandas-dev/pandas/issues/13874))

+   `Categorical.from_array` 已被弃用,并将在将来的版本中移除 ([GH 13854](https://github.com/pandas-dev/pandas/issues/13854))  ## 移除之前版本的弃用/更改

+   `SparsePanel`类已删除([GH 13778](https://github.com/pandas-dev/pandas/issues/13778))

+   `pd.sandbox`模块已删除,改为使用外部库`pandas-qt`([GH 13670](https://github.com/pandas-dev/pandas/issues/13670))

+   `pandas.io.data`和`pandas.io.wb`模块已删除,改为使用[pandas-datareader 包](https://github.com/pydata/pandas-datareader)([GH 13724](https://github.com/pandas-dev/pandas/issues/13724))

+   `pandas.tools.rplot`模块已删除,改为使用[seaborn 包](https://github.com/mwaskom/seaborn)([GH 13855](https://github.com/pandas-dev/pandas/issues/13855))

+   `DataFrame.to_csv()`已删除`engine`参数,自 0.17.1 起已弃用([GH 11274](https://github.com/pandas-dev/pandas/issues/11274),[GH 13419](https://github.com/pandas-dev/pandas/issues/13419))

+   `DataFrame.to_dict()`已删除`outtype`参数,改为使用`orient`([GH 13627](https://github.com/pandas-dev/pandas/issues/13627),[GH 8486](https://github.com/pandas-dev/pandas/issues/8486))

+   `pd.Categorical`已删除直接设置`ordered`属性,改为使用`set_ordered`方法([GH 13671](https://github.com/pandas-dev/pandas/issues/13671))

+   `pd.Categorical`已删除`levels`属性,改为使用`categories`([GH 8376](https://github.com/pandas-dev/pandas/issues/8376))

+   `DataFrame.to_sql()`已删除`flavor`参数中的`mysql`选项([GH 13611](https://github.com/pandas-dev/pandas/issues/13611))

+   `Panel.shift()`已删除`lags`参数,改为使用`periods`([GH 14041](https://github.com/pandas-dev/pandas/issues/14041))

+   `pd.Index`已删除`diff`方法,改为使用`difference`([GH 13669](https://github.com/pandas-dev/pandas/issues/13669))

+   `pd.DataFrame`已删除`to_wide`方法,改为使用`to_panel`([GH 14039](https://github.com/pandas-dev/pandas/issues/14039))

+   `Series.to_csv`已删除`nanRep`参数,改为使用`na_rep`([GH 13804](https://github.com/pandas-dev/pandas/issues/13804))

+   `Series.xs`、`DataFrame.xs`、`Panel.xs`、`Panel.major_xs`和`Panel.minor_xs`已删除`copy`参数([GH 13781](https://github.com/pandas-dev/pandas/issues/13781))

+   `str.split`已删除`return_type`参数,改为使用`expand`([GH 13701](https://github.com/pandas-dev/pandas/issues/13701))

+   自 0.17.0 起,已删除遗留时间规则(偏移别名),此前已弃用(自 0.8.0 以来已是别名)([GH 13590](https://github.com/pandas-dev/pandas/issues/13590),[GH 13868](https://github.com/pandas-dev/pandas/issues/13868))。现在遗留时间规则会引发`ValueError`。当前支持的偏移列表,请参见这里。

+   `DataFrame.plot.box`和`DataFrame.boxplot`的`return_type`参数的默认值从`None`更改为`"axes"`。这些方法现在默认返回 matplotlib axes 而不是艺术家字典。参见这里([GH 6581](https://github.com/pandas-dev/pandas/issues/6581))

+   `pandas.io.sql`模块中的`tquery`和`uquery`函数已删除([GH 5950](https://github.com/pandas-dev/pandas/issues/5950))  ## 性能改进

+   改进了稀疏`IntIndex.intersect`的性能([GH 13082](https://github.com/pandas-dev/pandas/issues/13082))

+   当块数量较多时,使用`BlockIndex`可以提高稀疏算术性能,尽管在这种情况下建议使用`IntIndex`([GH 13082](https://github.com/pandas-dev/pandas/issues/13082))

+   `DataFrame.quantile()`的性能改进,现在它是按块操作的([GH 11623](https://github.com/pandas-dev/pandas/issues/11623))

+   在 Python 3 中改进了 float64 哈希表操作的性能,修复了一些非常慢的索引和 groupby 操作([GH 13166](https://github.com/pandas-dev/pandas/issues/13166),[GH 13334](https://github.com/pandas-dev/pandas/issues/13334))

+   改进了`DataFrameGroupBy.transform`的性能([GH 12737](https://github.com/pandas-dev/pandas/issues/12737))

+   改进了`Index`和`Series`的`.duplicated`的性能([GH 10235](https://github.com/pandas-dev/pandas/issues/10235))

+   改进了`Index.difference`的性能([GH 12044](https://github.com/pandas-dev/pandas/issues/12044))

+   改进了`RangeIndex.is_monotonic_increasing`和`is_monotonic_decreasing`的性能([GH 13749](https://github.com/pandas-dev/pandas/issues/13749))

+   在`DatetimeIndex`中改进了日期时间字符串解析的性能([GH 13692](https://github.com/pandas-dev/pandas/issues/13692))

+   改进了`Period`的哈希性能([GH 12817](https://github.com/pandas-dev/pandas/issues/12817))

+   改进了带时区的日期时间的`factorize`性能([GH 13750](https://github.com/pandas-dev/pandas/issues/13750))

+   通过在更大的索引上懒惰地创建索引哈希表来改进了性能([GH 14266](https://github.com/pandas-dev/pandas/issues/14266))

+   改进了`groupby.groups`的性能([GH 14293](https://github.com/pandas-dev/pandas/issues/14293))

+   在内省内存使用量时,不必要地实例化 MultiIndex([GH 14308](https://github.com/pandas-dev/pandas/issues/14308))  ## 错误修复

+   `groupby().shift()`中的错误,在按列分组时出现缺失值时,可能导致段错误或数据损坏([GH 13813](https://github.com/pandas-dev/pandas/issues/13813))

+   在`groupby().cumsum()`中存在错误,当`axis=1`时,计算`cumprod`。([GH 13994](https://github.com/pandas-dev/pandas/issues/13994))

+   `pd.to_timedelta()`中的错误,在这里`errors`参数未被尊重([GH 13613](https://github.com/pandas-dev/pandas/issues/13613))

+   在 `io.json.json_normalize()` 中,非 ASCII 键引发异常存在错误([GH 13213](https://github.com/pandas-dev/pandas/issues/13213))

+   在 `.plot()` 中将非默认索引的 `Series` 作为 `xerr` 或 `yerr` 传递时存在错误([GH 11858](https://github.com/pandas-dev/pandas/issues/11858))

+   在区域图绘制中,如果启用了子图或在绘图后移动图例,则图例会被错误地绘制(需要 matplotlib 1.5.0 正确绘制区域图图例)([GH 9161](https://github.com/pandas-dev/pandas/issues/9161), [GH 13544](https://github.com/pandas-dev/pandas/issues/13544))

+   在使用对象数据类型 `Index` 进行 `DataFrame` 赋值时存在错误,导致结果列对原始对象可变([GH 13522](https://github.com/pandas-dev/pandas/issues/13522))

+   在 matplotlib `AutoDataFormatter` 中存在错误;这恢复了第二个缩放格式和重新添加了微秒缩放格式([GH 13131](https://github.com/pandas-dev/pandas/issues/13131))

+   在具有固定格式和指定 `start` 和/或 `stop` 的 `HDFStore` 中进行选择时,现在将返回所选范围([GH 8287](https://github.com/pandas-dev/pandas/issues/8287))

+   在 `Categorical.from_codes()` 中传递无效的 `ordered` 参数时引发了一个无用的错误([GH 14058](https://github.com/pandas-dev/pandas/issues/14058))

+   在 Windows 上从整数元组构建 `Series` 时未返回默认数据类型(int64)存在错误([GH 13646](https://github.com/pandas-dev/pandas/issues/13646))

+   在 `TimedeltaIndex` 添加日期时间对象时,未捕获溢出错误存在错误([GH 14068](https://github.com/pandas-dev/pandas/issues/14068))

+   在多次调用相同对象时,`.groupby(..).resample(..)` 存在错误([GH 13174](https://github.com/pandas-dev/pandas/issues/13174))

+   在索引名称为 Unicode 字符串时,`.to_records()` 存在错误([GH 13172](https://github.com/pandas-dev/pandas/issues/13172))

+   在未实现对象上调用 `.memory_usage()` 存在错误([GH 12924](https://github.com/pandas-dev/pandas/issues/12924))

+   `Series.quantile` 中存在 nan 值的回归问题(也出现在 `.median()` 和 `.describe()` 中);此外,现在使用分位数对 `Series` 进行命名([GH 13098](https://github.com/pandas-dev/pandas/issues/13098), [GH 13146](https://github.com/pandas-dev/pandas/issues/13146))

+   在具有日期时间值和缺失组的 `SeriesGroupBy.transform` 中存在错误([GH 13191](https://github.com/pandas-dev/pandas/issues/13191))

+   空 `Series` 在日期时间类似的数值操作中被错误地强制转换存在错误([GH 13844](https://github.com/pandas-dev/pandas/issues/13844))

+   在传递包含带时区的日期时间的 `Categorical` 时存在错误([GH 14190](https://github.com/pandas-dev/pandas/issues/14190))

+   `Series.str.extractall()` 中的 `str` 索引存在错误引发 `ValueError`([GH 13156](https://github.com/pandas-dev/pandas/issues/13156))

+   在带有单个组和量词的 `Series.str.extractall()` 中出现的 bug([GH 13382](https://github.com/pandas-dev/pandas/issues/13382))。

+   在 `DatetimeIndex` 和 `Period` 相减时引发 `ValueError` 或 `AttributeError` 而不是 `TypeError` 的 bug([GH 13078](https://github.com/pandas-dev/pandas/issues/13078))。

+   在创建带有 `NaN` 和 `NaT` 混合数据的 `Index` 和 `Series` 时可能没有 `datetime64` dtype 的 bug([GH 13324](https://github.com/pandas-dev/pandas/issues/13324))。

+   在 `Index` 和 `Series` 可能会忽略 `np.datetime64('nat')` 和 `np.timdelta64('nat')` 来推断 dtype 时出现的 bug([GH 13324](https://github.com/pandas-dev/pandas/issues/13324))。

+   在 `PeriodIndex` 和 `Period` 相减时引发 `AttributeError` 的 bug([GH 13071](https://github.com/pandas-dev/pandas/issues/13071))。

+   在某些情况下返回一个 `float64` 索引的 `PeriodIndex` 构造中出现的 bug([GH 13067](https://github.com/pandas-dev/pandas/issues/13067))。

+   在使用 `PeriodIndex` 时,当为空时不适当地更改其 `freq` 的 `.resample(..)` 中出现的 bug([GH 13067](https://github.com/pandas-dev/pandas/issues/13067))。

+   在使用 `PeriodIndex` 时,当为空时不适当地保留其类型或名称的 `.resample(..)` 中出现的 bug([GH 13212](https://github.com/pandas-dev/pandas/issues/13212))。

+   在使用`groupby(..).apply(..)`时出现的 bug,当传递的函数每组返回标量值时([GH 13468](https://github.com/pandas-dev/pandas/issues/13468))。

+   在使用`groupby(..).resample(..)`时出现的 bug,传递某些关键字会引发异常([GH 13235](https://github.com/pandas-dev/pandas/issues/13235))。

+   在依赖索引排序以获得正确结果的 tz-aware `DateTimeIndex` 上执行 `.tz_convert` 时出现的 bug([GH 13306](https://github.com/pandas-dev/pandas/issues/13306))。

+   在使用 `dateutil.tz.tzlocal` 的 `.tz_localize` 中可能返回不正确结果的 bug([GH 13583](https://github.com/pandas-dev/pandas/issues/13583))。

+   在使用 `dateutil.tz.tzlocal` 的 `DatetimeTZDtype` dtype 时无法被视为有效 dtype 的 bug([GH 13583](https://github.com/pandas-dev/pandas/issues/13583))。

+   在使用`pd.read_hdf()`时的 bug,尝试加载一个只有一个数据集且有一个或多个分类列的 HDF 文件会失败,除非将 key 参数设置为数据集的名称([GH 13231](https://github.com/pandas-dev/pandas/issues/13231))。

+   在 `.rolling()` 中允许使用负整数窗口构造 `Rolling()` 对象的 bug,但后来在聚合时会失败([GH 13383](https://github.com/pandas-dev/pandas/issues/13383))。

+   在使用元组值数据和数值索引的 `Series` 索引时出现的 bug([GH 13509](https://github.com/pandas-dev/pandas/issues/13509))。

+   在打印 `pd.DataFrame` 时,具有 `object` dtype 的不寻常元素导致段错误的 bug([GH 13717](https://github.com/pandas-dev/pandas/issues/13717))。

+   在排名 `Series` 时可能导致段错误的 bug([GH 13445](https://github.com/pandas-dev/pandas/issues/13445))。

+   各种索引类型中的错误,未传递传入索引的名称([GH 12309](https://github.com/pandas-dev/pandas/issues/12309))

+   `DatetimeIndex` 中的错误,未能遵守 `copy=True`([GH 13205](https://github.com/pandas-dev/pandas/issues/13205))

+   `DatetimeIndex.is_normalized` 中的错误会在本地时区的标准化 `date_range` 的情况下返回错误结果([GH 13459](https://github.com/pandas-dev/pandas/issues/13459))

+   `pd.concat` 和 `.append` 中可能将 `datetime64` 和 `timedelta` 强制转换为包含 Python 内置 `datetime` 或 `timedelta` 而不是 `Timestamp` 或 `Timedelta` 的 `object` 类型([GH 13626](https://github.com/pandas-dev/pandas/issues/13626))

+   `PeriodIndex.append` 中的错误可能在结果为 `object` 类型时引发 `AttributeError`([GH 13221](https://github.com/pandas-dev/pandas/issues/13221))

+   `CategoricalIndex.append` 中的错误可能接受普通的 `list`([GH 13626](https://github.com/pandas-dev/pandas/issues/13626))

+   `pd.concat` 和 `.append` 中相同时区的错误被重置为 UTC([GH 7795](https://github.com/pandas-dev/pandas/issues/7795))

+   `Series` 和 `DataFrame` 中的 `.append` 在数据包含接近 DST 边界的日期时间时引发 `AmbiguousTimeError`([GH 13626](https://github.com/pandas-dev/pandas/issues/13626))

+   `DataFrame.to_csv()` 中的错误,即使只为非数字值指定引号,浮点值也会被引用([GH 12922](https://github.com/pandas-dev/pandas/issues/12922),[GH 13259](https://github.com/pandas-dev/pandas/issues/13259))

+   `DataFrame.describe()` 中引发 `ValueError` 仅包含布尔列时([GH 13898](https://github.com/pandas-dev/pandas/issues/13898))

+   `MultiIndex` 切片中,当级别不唯一时返回额外元素的错误([GH 12896](https://github.com/pandas-dev/pandas/issues/12896))

+   `.str.replace` 中的错误未对无效替换引发 `TypeError`([GH 13438](https://github.com/pandas-dev/pandas/issues/13438))

+   `MultiIndex.from_arrays` 中未检查输入数组长度是否匹配的错误([GH 13599](https://github.com/pandas-dev/pandas/issues/13599))

+   `cartesian_product` 和 `MultiIndex.from_product` 中可能由于空输入数组而引发错误([GH 12258](https://github.com/pandas-dev/pandas/issues/12258))

+   `pd.read_csv()` 中,在极少情况下在流/文件上大块迭代时可能导致段错误或损坏([GH 13703](https://github.com/pandas-dev/pandas/issues/13703))

+   `pd.read_csv()` 中的错误导致在为 `na_values` 传入包含标量的字典时引发错误([GH 12224](https://github.com/pandas-dev/pandas/issues/12224))

+   `pd.read_csv()` 中的错误导致 BOM 文件被错误解析而不忽略 BOM([GH 4793](https://github.com/pandas-dev/pandas/issues/4793))

+   `pd.read_csv()` 中使用 `engine='python'` 时,当传入 numpy 数组作为 `usecols` 时引发错误([GH 12546](https://github.com/pandas-dev/pandas/issues/12546))

+   在`pd.read_csv()`中存在一个 bug,当以日期形式解析时,使用`thousands`参数时,索引列被错误解析([GH 14066](https://github.com/pandas-dev/pandas/issues/14066))

+   在`pd.read_csv()`中存在一个 bug,使用`engine='python'`时,数据转换为数值后未检测到`NaN`值([GH 13314](https://github.com/pandas-dev/pandas/issues/13314))

+   在`pd.read_csv()`中存在一个 bug,`nrows`参数在两种引擎中都没有得到正确验证([GH 10476](https://github.com/pandas-dev/pandas/issues/10476))

+   在`pd.read_csv()`中存在一个 bug,使用`engine='python'`时,混合大小写形式的无穷大未被正确解释([GH 13274](https://github.com/pandas-dev/pandas/issues/13274))

+   在`pd.read_csv()`中存在一个 bug,使用`engine='python'`时,未解析尾随的`NaN`值([GH 13320](https://github.com/pandas-dev/pandas/issues/13320))

+   在`pd.read_csv()`中存在一个 bug,使用`engine='python'`时,在 Windows 上使用 Python 3 读取`tempfile.TemporaryFile`时([GH 13398](https://github.com/pandas-dev/pandas/issues/13398))

+   在`pd.read_csv()`中存在一个 bug,阻止`usecols`参数接受单字节 unicode 字符串([GH 13219](https://github.com/pandas-dev/pandas/issues/13219))

+   在`pd.read_csv()`中存在一个 bug,阻止`usecols`为空集合([GH 13402](https://github.com/pandas-dev/pandas/issues/13402))

+   在`pd.read_csv()`的 C 引擎中存在一个 bug,NULL 字符未被解析为 NULL([GH 14012](https://github.com/pandas-dev/pandas/issues/14012))

+   在`pd.read_csv()`中存在一个 bug,使用`engine='c'`时,即使`quoting`指定为`None`,也不接受 NULL `quotechar`([GH 13411](https://github.com/pandas-dev/pandas/issues/13411))

+   在`pd.read_csv()`中存在一个 bug,使用`engine='c'`时,当引号指定为非数字时,字段未正确转换为浮点数([GH 13411](https://github.com/pandas-dev/pandas/issues/13411))

+   在 Python 2.x 中存在一个 bug,`pd.read_csv()`无法处理非 UTF8 编码的多字符分隔数据([GH 3404](https://github.com/pandas-dev/pandas/issues/3404))

+   在`pd.read_csv()`中存在一个 bug,当 utf-xx 的别名(例如 UTF-xx, UTF_xx, utf_xx)时,引发 UnicodeDecodeError([GH 13549](https://github.com/pandas-dev/pandas/issues/13549))

+   在`pd.read_csv`、`pd.read_table`、`pd.read_fwf`、`pd.read_stata`和`pd.read_sas`中存在一个 bug,如果`chunksize`和`iterator`都是`None`,则解析器打开文件但不关闭文件。([GH 13940](https://github.com/pandas-dev/pandas/issues/13940))

+   在`StataReader`、`StataWriter`、`XportReader`和`SAS7BDATReader`中存在一个 bug,当出现错误时,文件未被正确关闭。([GH 13940](https://github.com/pandas-dev/pandas/issues/13940))

+   在`pd.pivot_table()`中存在一个 bug,当`aggfunc`是一个列表时,`margins_name`被忽略([GH 13354](https://github.com/pandas-dev/pandas/issues/13354))

+   `pd.Series.str.zfill`、`center`、`ljust`、`rjust` 和 `pad` 中的 Bug,当传递非整数时,不会引发 `TypeError`([GH 13598](https://github.com/pandas-dev/pandas/issues/13598))

+   在 `TimedeltaIndex` 中检查是否有任何空对象的 Bug,始终返回 `True`([GH 13603](https://github.com/pandas-dev/pandas/issues/13603))

+   `Series` 算术中的 Bug,如果包含类似日期时间的 `object` 数据类型,则引发 `TypeError`([GH 13043](https://github.com/pandas-dev/pandas/issues/13043))

+   `Series.isnull()` 和 `Series.notnull()` 中的 Bug 忽略了 `Period('NaT')`([GH 13737](https://github.com/pandas-dev/pandas/issues/13737))

+   `Series.fillna()` 和 `Series.dropna()` 中的 Bug 不会影响到 `Period('NaT')`([GH 13737](https://github.com/pandas-dev/pandas/issues/13737))

+   `.fillna(value=np.nan)` 中的 Bug 在类别数据类型的 `Series` 上错误地引发 `KeyError`([GH 14021](https://github.com/pandas-dev/pandas/issues/14021))

+   扩展数据类型创建中的 Bug,创建的类型不是/不相同([GH 13285](https://github.com/pandas-dev/pandas/issues/13285))

+   `.resample(..)` 中的 Bug,IPython 内省触发了不正确的警告([GH 13618](https://github.com/pandas-dev/pandas/issues/13618))

+   `NaT` - `Period` 中的 Bug 引发 `AttributeError`([GH 13071](https://github.com/pandas-dev/pandas/issues/13071))

+   `Series` 比较中的 Bug,如果 rhs 包含 `NaT`,可能输出不正确的结果([GH 9005](https://github.com/pandas-dev/pandas/issues/9005))

+   `Series` 和 `Index` 比较中的 Bug,如果包含 `object` 数据类型的 `NaT`,可能输出不正确的结果([GH 13592](https://github.com/pandas-dev/pandas/issues/13592))

+   `Period` 加法中的 Bug 如果 `Period` 在右侧,则引发 `TypeError`([GH 13069](https://github.com/pandas-dev/pandas/issues/13069))

+   `Period` 和 `Series` 或 `Index` 比较中的 Bug 引发 `TypeError`([GH 13200](https://github.com/pandas-dev/pandas/issues/13200))

+   `pd.set_eng_float_format()` 中的 Bug,会阻止 NaN 和 Inf 进行格式化([GH 11981](https://github.com/pandas-dev/pandas/issues/11981))

+   `.unstack` 中的 Bug,具有 `Categorical` 数据类型会重置 `.ordered` 为 `True`([GH 13249](https://github.com/pandas-dev/pandas/issues/13249))

+   清除一些在日期时间解析中的编译时警告([GH 13607](https://github.com/pandas-dev/pandas/issues/13607))

+   `factorize` 中的 Bug 如果数据中包含接近 DST 边界的日期时间,则会引发 `AmbiguousTimeError`([GH 13750](https://github.com/pandas-dev/pandas/issues/13750))

+   `.set_index` 中的 Bug 如果新索引包含 DST 边界和多级,则引发 `AmbiguousTimeError`([GH 12920](https://github.com/pandas-dev/pandas/issues/12920))

+   `.shift` 中的 Bug 如果数据中包含接近 DST 边界的日期时间,则会引发 `AmbiguousTimeError`([GH 13926](https://github.com/pandas-dev/pandas/issues/13926))

+   `pd.read_hdf()` 中的 Bug,在不匹配任何值的查询下,返回了不正确的结果,当 `DataFrame` 具有 `categorical` 列时([GH 13792](https://github.com/pandas-dev/pandas/issues/13792))

+   在使用非 lexsorted MultiIndex 进行索引时,`.iloc`中存在一个 bug([GH 13797](https://github.com/pandas-dev/pandas/issues/13797))

+   在使用日期字符串在逆向排序的`DatetimeIndex`中进行索引时,`.loc`可能存��bug([GH 14316](https://github.com/pandas-dev/pandas/issues/14316))

+   在处理零维 NumPy 数组时,`Series`比较运算符可能存在 bug([GH 13006](https://github.com/pandas-dev/pandas/issues/13006))

+   `.combine_first`中的一个 bug 可能会返回不正确的`dtype`([GH 7630](https://github.com/pandas-dev/pandas/issues/7630),[GH 10567](https://github.com/pandas-dev/pandas/issues/10567))

+   `groupby`中的一个 bug,`apply`的返回结果取决于第一个结果是否为`None`([GH 12824](https://github.com/pandas-dev/pandas/issues/12824))

+   `groupby(..).nth()`中的一个 bug,如果在`.head()/.tail()`之后调用,组键会不一致地包含在内([GH 12839](https://github.com/pandas-dev/pandas/issues/12839))

+   `.to_html`、`.to_latex`和`.to_string`中存在一个 bug,通过`formatters`关键字传递的自定义日期时间格式化程序会被静默忽略([GH 10690](https://github.com/pandas-dev/pandas/issues/10690))

+   在`DataFrame.iterrows()`中,如果定义了`Series`子类,则不会产生 bug([GH 13977](https://github.com/pandas-dev/pandas/issues/13977))

+   在`pd.to_numeric`中存在一个 bug,当`errors='coerce'`且输入包含不可哈希对象时([GH 13324](https://github.com/pandas-dev/pandas/issues/13324))

+   在无效的`Timedelta`算术和比较中可能会引发`ValueError`而不是`TypeError`的 bug([GH 13624](https://github.com/pandas-dev/pandas/issues/13624))

+   在`to_datetime`和`DatetimeIndex`中无效的日期时间解析可能会引发`TypeError`而不是`ValueError`的 bug([GH 11169](https://github.com/pandas-dev/pandas/issues/11169),[GH 11287](https://github.com/pandas-dev/pandas/issues/11287))

+   在使用 tz-aware `Timestamp`和不匹配的`tz`选项创建`Index`时,可能会错误地强制转换时区的 bug([GH 13692](https://github.com/pandas-dev/pandas/issues/13692))

+   在纳秒频率的`DatetimeIndex`中,指定`end`的时间戳可能不包括在内的 bug([GH 13672](https://github.com/pandas-dev/pandas/issues/13672))

+   在使用`np.timedelta64`设置切片时,`Series`可能存在 bug([GH 14155](https://github.com/pandas-dev/pandas/issues/14155))

+   在`Index`中,如果`datetime`超出`datetime64[ns]`边界,则会引发`OutOfBoundsDatetime`,而不是强制转换为`object` dtype 的 bug([GH 13663](https://github.com/pandas-dev/pandas/issues/13663))

+   在`Index`中可能会忽略指定的`datetime64`或`timedelta64`作为`dtype`传递的 bug([GH 13981](https://github.com/pandas-dev/pandas/issues/13981))

+   可以创建没有参数的`RangeIndex`,而不是引发`TypeError`的 bug([GH 13793](https://github.com/pandas-dev/pandas/issues/13793))

+   在`.value_counts()`中,如果数据超出`datetime64[ns]`边界,则会引发`OutOfBoundsDatetime`的 bug([GH 13663](https://github.com/pandas-dev/pandas/issues/13663))

+   在`DatetimeIndex`中存在错误,如果输入的`np.datetime64`单位不是`ns`,可能会引发`OutOfBoundsDatetime`([GH 9114](https://github.com/pandas-dev/pandas/issues/9114))。

+   使用具有非`ns`单位的`np.datetime64`创建 Series 时存在错误,结果为`object` dtype 会得到不正确的值([GH 13876](https://github.com/pandas-dev/pandas/issues/13876))。

+   在带有时间数据的`resample`中存在错误,数据被强制转换为浮点数([GH 13119](https://github.com/pandas-dev/pandas/issues/13119))。

+   `pd.isnull()` 和 `pd.notnull()` 存在错误,如果输入的类似日期时间的对象单位不是`ns`,会引发`TypeError`([GH 13389](https://github.com/pandas-dev/pandas/issues/13389))。

+   在`pd.merge()`中存在错误,如果输入的类似日期时间的对象单位不是`ns`,可能会引发`TypeError`([GH 13389](https://github.com/pandas-dev/pandas/issues/13389))。

+   在`HDFStore`/`read_hdf()`中存在错误,如果设置了`tz`,会丢弃`DatetimeIndex.name`([GH 13884](https://github.com/pandas-dev/pandas/issues/13884))。

+   在`Categorical.remove_unused_categories()`中存在错误,会将`.codes`的 dtype 更改为平台整数([GH 13261](https://github.com/pandas-dev/pandas/issues/13261))。

+   在`groupby`中,使用`as_index=False`在包括分类变量的多个列进行分组时,返回全部 NaN 时存在错误([GH 13204](https://github.com/pandas-dev/pandas/issues/13204))。

+   在`df.groupby(...)[...]`中存在错误,使用`Int64Index`进行 getitem 时会引发错误([GH 13731](https://github.com/pandas-dev/pandas/issues/13731))。

+   对于`DataFrame.style`分配给索引名称的 CSS 类存在错误。之前它们被分配为`"col_heading level<n> col<c>"`,其中`n`是级别数加 1。现在它们被分配为`"index_name level<n>"`,其中`n`是该 MultiIndex 的正确级别。

+   在`pd.read_gbq()`中存在错误,可能会引发`ImportError: No module named discovery`,因为与另一个名为 apiclient 的 Python 包发生命名冲突([GH 13454](https://github.com/pandas-dev/pandas/issues/13454))。

+   在`Index.union`中存在错误,使用具有命名空索引时返回不正确的结果([GH 13432](https://github.com/pandas-dev/pandas/issues/13432))。

+   在`Index.difference`和`DataFrame.join`中存在错误,在使用混合整数索引时,Python3 中可能会引发错误([GH 13432](https://github.com/pandas-dev/pandas/issues/13432),[GH 12814](https://github.com/pandas-dev/pandas/issues/12814))。

+   在从具有时区信息的`datetime.datetime`中减去具有时区信息的`datetime64`系列时存在错误([GH 14088](https://github.com/pandas-dev/pandas/issues/14088))。

+   在`DataFrame.contains`中存在错误,当 DataFrame 包含具有 NaN 值的 MultiIndex 时([GH 13511](https://github.com/pandas-dev/pandas/issues/13511))。

+   在无效的频率偏移字符串(如“D1”,“-2-3H”)可能不会引发`ValueError`([GH 13930](https://github.com/pandas-dev/pandas/issues/13930))。

+   在具有`RangeIndex`级别的分层框架的`concat`和`groupby`存在错误([GH 13542](https://github.com/pandas-dev/pandas/issues/13542))。

+   `Series.str.contains()` 中的一个 bug,用于只包含 `NaN` 值的 `object` dtype Series([GH 14171](https://github.com/pandas-dev/pandas/issues/14171))

+   在 groupby 数据框的 `agg()` 函数中存在一个 bug,会将 `datetime64[ns]` 列的 dtype 更改为 `float64`([GH 12821](https://github.com/pandas-dev/pandas/issues/12821))

+   使用 NumPy ufunc 与 `PeriodIndex` 进行整数加法或减法时引发 `IncompatibleFrequency` 的一个 bug。请注意,推荐使用标准运算符(如 `+` 或 `-`),因为标准运算符使用更高效的路径([GH 13980](https://github.com/pandas-dev/pandas/issues/13980))

+   在 `NaT` 上进行操作的一个 bug,返回 `float` 而不是 `datetime64[ns]`([GH 12941](https://github.com/pandas-dev/pandas/issues/12941))

+   `Series` 的灵活算术方法(如 `.add()`)中的一个 bug,在 `axis=None` 时引发 `ValueError`([GH 13894](https://github.com/pandas-dev/pandas/issues/13894))

+   在具有 `MultiIndex` 列的 `DataFrame.to_csv()` 中添加了一个多余的空行([GH 6618](https://github.com/pandas-dev/pandas/issues/6618))

+   `DatetimeIndex`、`TimedeltaIndex` 和 `PeriodIndex.equals()` 中的一个 bug,当输入不是 `Index` 但包含相同值时,可能会返回 `True`([GH 13107](https://github.com/pandas-dev/pandas/issues/13107))

+   在具有时区的日期时间上进行赋值的一个 bug,如果包含接近 DST 边界的日期时间,则可能不起作用([GH 14146](https://github.com/pandas-dev/pandas/issues/14146))

+   `pd.eval()` 和 `HDFStore` 查询中的一个 bug,在 python 2 中截断长浮点文字([GH 14241](https://github.com/pandas-dev/pandas/issues/14241))

+   `Index` 中的一个 bug,在 df 中不存在列且列包含重复值时,引发 `KeyError` 并显示不正确的列名([GH 13822](https://github.com/pandas-dev/pandas/issues/13822))

+   在创建 `Period` 和 `PeriodIndex` 时,当频率具有组合偏移别名时,可能会生成错误的日期([GH 13874](https://github.com/pandas-dev/pandas/issues/13874))

+   当以整数 `line_width` 和 `index=False` 调用 `.to_string()` 时,会引发 UnboundLocalError 异常,因为在赋值之前引用了 `idx`。

+   `eval()` 中存在的一个 bug,即 `resolvers` 参数不接受列表([GH 14095](https://github.com/pandas-dev/pandas/issues/14095))

+   `stack`、`get_dummies`、`make_axis_dummies` 中存在的 bug,不会在(多重)索引中保留分类 dtype([GH 13854](https://github.com/pandas-dev/pandas/issues/13854))

+   `PeriodIndex` 现在可以接受包含 `pd.NaT` 的 `list` 和 `array`([GH 13430](https://github.com/pandas-dev/pandas/issues/13430))

+   `df.groupby` 中的一个 bug,如果分组的数据框包含空的 bin,则 `.median()` 返回任意值([GH 13629](https://github.com/pandas-dev/pandas/issues/13629))

+   `Index.copy()` 中的一个 bug,会忽略 `name` 参数([GH 14302](https://github.com/pandas-dev/pandas/issues/14302))

总共有 117 人为此版本提交了补丁。 带有 “+” 的人表示首次为其贡献了补丁。

+   Adrien Emery +

+   Alex Alekseyev

+   Alex Vig +

+   Allen Riddell +

+   Amol +

+   Amol Agrawal +

+   Andy R. Terrel +

+   Anthonios Partheniou

+   Ben Kandel +

+   Bob Baxley +

+   Brett Rosen +

+   Camilo Cota +

+   Chris

+   Chris Grinolds

+   Chris Warth

+   Christian Hudon

+   Christopher C. Aycock

+   Daniel Siladji +

+   Douglas McNeil

+   Drewrey Lupton +

+   Eduardo Blancas Reyes +

+   Elliot Marsden +

+   Evan Wright

+   Felix Marczinowski +

+   Francis T. O’Donovan

+   Geraint Duck +

+   Giacomo Ferroni +

+   Grant Roch +

+   Gábor Lipták

+   Haleemur Ali +

+   Hassan Shamim +

+   Iulius Curt +

+   Ivan Nazarov +

+   Jeff Reback

+   Jeffrey Gerard +

+   Jenn Olsen +

+   Jim Crist

+   Joe Jevnik

+   John Evans +

+   John Freeman

+   John Liekezer +

+   John W. O’Brien

+   John Zwinck +

+   Johnny Gill +

+   Jordan Erenrich +

+   Joris Van den Bossche

+   Josh Howes +

+   Jozef Brandys +

+   Ka Wo Chen

+   Kamil Sindi +

+   Kerby Shedden

+   Kernc +

+   Kevin Sheppard

+   Matthieu Brucher +

+   Maximilian Roos

+   Michael Scherer +

+   Mike Graham +

+   Mortada Mehyar

+   Muhammad Haseeb Tariq +

+   Nate George +

+   Neil Parley +

+   Nicolas Bonnotte

+   OXPHOS

+   Pan Deng / Zora +

+   Paul +

+   Paul Mestemaker +

+   Pauli Virtanen

+   Pawel Kordek +

+   Pietro Battiston

+   Piotr Jucha +

+   Ravi Kumar Nimmi +

+   Robert Gieseke

+   Robert Kern +

+   Roger Thomas

+   Roy Keyes +

+   Russell Smith +

+   Sahil Dua +

+   Sanjiv Lobo +

+   Sašo Stanovnik +

+   Shawn Heide +

+   Sinhrks

+   Stephen Kappel +

+   Steve Choi +

+   Stewart Henderson +

+   Sudarshan Konge +

+   Thomas A Caswell

+   Tom Augspurger

+   Tom Bird +

+   Uwe Hoffmann +

+   WillAyd +

+   Xiang Zhang +

+   YG-Riku +

+   Yadunandan +

+   Yaroslav Halchenko

+   Yuichiro Kaneko +

+   adneu

+   agraboso +

+   babakkeyvani +

+   c123w +

+   chris-b1

+   cmazzullo +

+   conquistador1492 +

+   cr3 +

+   dsm054

+   gfyoung

+   harshul1610 +

+   iamsimha +

+   jackieleng +

+   mpuels +

+   pijucha +

+   priyankjain +

+   sinhrks

+   wcwagner +

+   yui-knk +

+   zhangjinjie +

+   znmean +

+   颜发才(Yan Facai) +  ## 新功能

### 函数 `merge_asof` 用于 asof 风格的时间序列连接

通过 `merge_asof()` 函数,我们添加了一个长期请求的功能,以支持时间序列的 asof 风格连接 ([GH 1870](https://github.com/pandas-dev/pandas/issues/1870), [GH 13695](https://github.com/pandas-dev/pandas/issues/13695), [GH 13709](https://github.com/pandas-dev/pandas/issues/13709), [GH 13902](https://github.com/pandas-dev/pandas/issues/13902))。完整文档在 这里。

`merge_asof()` 执行 asof 合并,类似于左连接,但我们匹配最近的键而不是相等的键。

```py
In [1]: left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]})

In [2]: right = pd.DataFrame({"a": [1, 2, 3, 6, 7], "right_val": [1, 2, 3, 6, 7]})

In [3]: left
Out[3]: 
 a left_val
0   1        a
1   5        b
2  10        c

[3 rows x 2 columns]

In [4]: right
Out[4]: 
 a  right_val
0  1          1
1  2          2
2  3          3
3  6          6
4  7          7

[5 rows x 2 columns] 

我们通常希望尽可能精确匹配,并在不可能时使用最近的值。

In [5]: pd.merge_asof(left, right, on="a")
Out[5]: 
 a left_val  right_val
0   1        a          1
1   5        b          3
2  10        c          7

[3 rows x 3 columns] 

我们还可以仅匹配具有先前数据而不是精确匹配的行。

In [6]: pd.merge_asof(left, right, on="a", allow_exact_matches=False)
Out[6]: 
 a left_val  right_val
0   1        a        NaN
1   5        b        3.0
2  10        c        7.0

[3 rows x 3 columns] 

在典型的时间序列示例中,我们有 trades 和 quotes,我们希望将它们进行 asof-join。这还说明了在合并之前使用 by 参数对数据进行分组。

In [7]: trades = pd.DataFrame(
 ...:    {
 ...:        "time": pd.to_datetime(
 ...:            [
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.038",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.048",
 ...:            ]
 ...:        ),
 ...:        "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"],
 ...:        "price": [51.95, 51.95, 720.77, 720.92, 98.00],
 ...:        "quantity": [75, 155, 100, 100, 100],
 ...:    },
 ...:    columns=["time", "ticker", "price", "quantity"],
 ...: )
 ...: 

In [8]: quotes = pd.DataFrame(
 ...:    {
 ...:        "time": pd.to_datetime(
 ...:            [
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.030",
 ...:                "20160525 13:30:00.041",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.049",
 ...:                "20160525 13:30:00.072",
 ...:                "20160525 13:30:00.075",
 ...:            ]
 ...:        ),
 ...:        "ticker": ["GOOG", "MSFT", "MSFT", "MSFT", "GOOG", "AAPL", "GOOG", "MSFT"],
 ...:        "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
 ...:        "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03],
 ...:    },
 ...:    columns=["time", "ticker", "bid", "ask"],
 ...: )
 ...: 
In [9]: trades
Out[9]: 
 time ticker   price  quantity
0 2016-05-25 13:30:00.023   MSFT   51.95        75
1 2016-05-25 13:30:00.038   MSFT   51.95       155
2 2016-05-25 13:30:00.048   GOOG  720.77       100
3 2016-05-25 13:30:00.048   GOOG  720.92       100
4 2016-05-25 13:30:00.048   AAPL   98.00       100

[5 rows x 4 columns]

In [10]: quotes
Out[10]: 
 time ticker     bid     ask
0 2016-05-25 13:30:00.023   GOOG  720.50  720.93
1 2016-05-25 13:30:00.023   MSFT   51.95   51.96
2 2016-05-25 13:30:00.030   MSFT   51.97   51.98
3 2016-05-25 13:30:00.041   MSFT   51.99   52.00
4 2016-05-25 13:30:00.048   GOOG  720.50  720.93
5 2016-05-25 13:30:00.049   AAPL   97.99   98.01
6 2016-05-25 13:30:00.072   GOOG  720.50  720.88
7 2016-05-25 13:30:00.075   MSFT   52.01   52.03

[8 rows x 4 columns] 

asof 合并在on上进行,通常是一个有序的日期时间字段,在本例中我们在by字段中使用了一个分组器。这类似于左外连接,只是自动进行前向填充,取最近的非 NaN 值。

In [11]: pd.merge_asof(trades, quotes, on="time", by="ticker")
Out[11]: 
 time ticker   price  quantity     bid     ask
0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN

[5 rows x 6 columns] 

这将返回一个合并的 DataFrame,其条目的顺序与原始的左侧传递的 DataFrame 相同(在本例中是trades),其中quotes的字段被合并。 ### 方法 .rolling() 现在支持时间序列

.rolling() 对象现在具有时间序列意识,并且可以接受时间序列偏移(或可转换的)作为window参数(GH 13327, GH 12995)。查看完整文档 here。

In [12]: dft = pd.DataFrame(
 ....:    {"B": [0, 1, 2, np.nan, 4]},
 ....:    index=pd.date_range("20130101 09:00:00", periods=5, freq="s"),
 ....: )
 ....: 

In [13]: dft
Out[13]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  2.0
2013-01-01 09:00:03  NaN
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

这是一个常规频率索引。使用整数窗口参数可以按窗口频率滚动。

In [14]: dft.rolling(2).sum()
Out[14]: 
 B
2013-01-01 09:00:00  NaN
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  NaN
2013-01-01 09:00:04  NaN

[5 rows x 1 columns]

In [15]: dft.rolling(2, min_periods=1).sum()
Out[15]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

指定偏移量可以更直观地指定滚动频率。

In [16]: dft.rolling("2s").sum()
Out[16]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

使用非常规但仍然单调的索引,使用整数窗口进行滚动不会产生任何特殊的计算。

In [17]: dft = pd.DataFrame(
 ....:    {"B": [0, 1, 2, np.nan, 4]},
 ....:    index=pd.Index(
 ....:        [
 ....:            pd.Timestamp("20130101 09:00:00"),
 ....:            pd.Timestamp("20130101 09:00:02"),
 ....:            pd.Timestamp("20130101 09:00:03"),
 ....:            pd.Timestamp("20130101 09:00:05"),
 ....:            pd.Timestamp("20130101 09:00:06"),
 ....:        ],
 ....:        name="foo",
 ....:    ),
 ....: )
 ....: 

In [18]: dft
Out[18]: 
 B
foo 
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  4.0

[5 rows x 1 columns]

In [19]: dft.rolling(2).sum()
Out[19]: 
 B
foo 
2013-01-01 09:00:00  NaN
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  NaN

[5 rows x 1 columns] 

使用时间规范为稀疏数据生成可变窗口。

In [20]: dft.rolling("2s").sum()
Out[20]: 
 B
foo 
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  4.0

[5 rows x 1 columns] 

此外,我们现在允许一个可选的on参数来指定 DataFrame 中的列(而不是默认的索引)。

In [21]: dft = dft.reset_index()

In [22]: dft
Out[22]: 
 foo    B
0 2013-01-01 09:00:00  0.0
1 2013-01-01 09:00:02  1.0
2 2013-01-01 09:00:03  2.0
3 2013-01-01 09:00:05  NaN
4 2013-01-01 09:00:06  4.0

[5 rows x 2 columns]

In [23]: dft.rolling("2s", on="foo").sum()
Out[23]: 
 foo    B
0 2013-01-01 09:00:00  0.0
1 2013-01-01 09:00:02  1.0
2 2013-01-01 09:00:03  3.0
3 2013-01-01 09:00:05  NaN
4 2013-01-01 09:00:06  4.0

[5 rows x 2 columns] 
```  ### 方法 `read_csv` 对重复列名的支持有所改进

重复列名 现在在`read_csv()`中得到支持,无论它们是否在文件中或作为`names`参数传递([GH 7160](https://github.com/pandas-dev/pandas/issues/7160), [GH 9424](https://github.com/pandas-dev/pandas/issues/9424))

```py
In [24]: data = "0,1,2\n3,4,5"

In [25]: names = ["a", "b", "a"] 

先前的行为:

In [2]: pd.read_csv(StringIO(data), names=names)
Out[2]:
 a  b  a
0  2  1  2
1  5  4  5 

第一个a列包含与第二个a列相同的数据,而应该包含值[0, 3]。

新行为:

In [26]: pd.read_csv(StringIO(data), names=names)
---------------------------------------------------------------------------
ValueError  Traceback (most recent call last)
Cell In[26], line 1
----> 1 pd.read_csv(StringIO(data), names=names)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:1026, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)
  1013 kwds_defaults = _refine_defaults_read(
  1014     dialect,
  1015     delimiter,
   (...)
  1022     dtype_backend=dtype_backend,
  1023 )
  1024 kwds.update(kwds_defaults)
-> 1026 return _read(filepath_or_buffer, kwds)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:617, in _read(filepath_or_buffer, kwds)
  614 nrows = kwds.get("nrows", None)
  616 # Check for duplicates in names.
--> 617 _validate_names(kwds.get("names", None))
  619 # Create the parser.
  620 parser = TextFileReader(filepath_or_buffer, **kwds)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:576, in _validate_names(names)
  574 if names is not None:
  575     if len(names) != len(set(names)):
--> 576         raise ValueError("Duplicate names are not allowed.")
  577     if not (
  578         is_list_like(names, allow_sets=False) or isinstance(names, abc.KeysView)
  579     ):
  580         raise ValueError("Names should be an ordered collection.")

ValueError: Duplicate names are not allowed. 
```  ### 方法 `read_csv` 直接支持解析 `Categorical`

当指定为 dtype 时,`read_csv()` 函数现在支持解析`Categorical`列([GH 10153](https://github.com/pandas-dev/pandas/issues/10153))。根据数据的结构,这可能导致比解析后转换为`Categorical`更快的解析时间和更低的内存使用。在这里查看 io 文档。

```py
In [27]: data = """
 ....: col1,col2,col3
 ....: a,b,1
 ....: a,b,2
 ....: c,d,3
 ....: """
 ....: 

In [28]: pd.read_csv(StringIO(data))
Out[28]: 
 col1 col2  col3
0    a    b     1
1    a    b     2
2    c    d     3

[3 rows x 3 columns]

In [29]: pd.read_csv(StringIO(data)).dtypes
Out[29]: 
col1    object
col2    object
col3     int64
Length: 3, dtype: object

In [30]: pd.read_csv(StringIO(data), dtype="category").dtypes
Out[30]: 
col1    category
col2    category
col3    category
Length: 3, dtype: object 

可以使用字典规范将单个列解析为 Categorical。

In [31]: pd.read_csv(StringIO(data), dtype={"col1": "category"}).dtypes
Out[31]: 
col1    category
col2      object
col3       int64
Length: 3, dtype: object 

注意

结果类别将始终被解析为字符串(对象 dtype)。如果类别是数值型的,则可以使用to_numeric() 函数进行转换,或者根据需要使用另一个转换器,如 to_datetime()。

In [32]: df = pd.read_csv(StringIO(data), dtype="category")

In [33]: df.dtypes
Out[33]: 
col1    category
col2    category
col3    category
Length: 3, dtype: object

In [34]: df["col3"]
Out[34]: 
0    1
1    2
2    3
Name: col3, Length: 3, dtype: category
Categories (3, object): ['1', '2', '3']

In [35]: new_categories = pd.to_numeric(df["col3"].cat.categories)

In [36]: df["col3"] = df["col3"].cat.rename_categories(new_categories)

In [37]: df["col3"]
Out[37]: 
0    1
1    2
2    3
Name: col3, Length: 3, dtype: category
Categories (3, int64): [1, 2, 3] 
```  ### 分类连接

+   添加了一个用于合并分类的函数`union_categoricals()`,请参阅 Unioning Categoricals ([GH 13361](https://github.com/pandas-dev/pandas/issues/13361), [GH 13763](https://github.com/pandas-dev/pandas/issues/13763), [GH 13846](https://github.com/pandas-dev/pandas/issues/13846), [GH 14173](https://github.com/pandas-dev/pandas/issues/14173))

    ```py
    In [38]: from pandas.api.types import union_categoricals

    In [39]: a = pd.Categorical(["b", "c"])

    In [40]: b = pd.Categorical(["a", "b"])

    In [41]: union_categoricals([a, b])
    Out[41]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['b', 'c', 'a'] 
    ```

+   `concat` 和 `append` 现在可以将具有不同 `categories` 的 `category` dtypes 连接为 `object` dtype ([GH 13524](https://github.com/pandas-dev/pandas/issues/13524))

    ```py
    In [42]: s1 = pd.Series(["a", "b"], dtype="category")

    In [43]: s2 = pd.Series(["b", "c"], dtype="category") 
    ```

**先前的行为**:

```py
In [1]: pd.concat([s1, s2])
ValueError: incompatible categories in categorical concat 

新行为:

In [44]: pd.concat([s1, s2])
Out[44]: 
0    a
1    b
0    b
1    c
Length: 4, dtype: object 
```  ### 半月偏移量

pandas 增加了新的频率偏移量,`SemiMonthEnd`('SM')和 `SemiMonthBegin`('SMS')。 这些提供了默认锚定到月中(15 号)和月底,以及月初(1 号)和 15 号的日期偏移量。 ([GH 1543](https://github.com/pandas-dev/pandas/issues/1543))

```py
In [45]: from pandas.tseries.offsets import SemiMonthEnd, SemiMonthBegin 

SemiMonthEnd:

In [46]: pd.Timestamp("2016-01-01") + SemiMonthEnd()
Out[46]: Timestamp('2016-01-15 00:00:00')

In [47]: pd.date_range("2015-01-01", freq="SM", periods=4)
Out[47]: DatetimeIndex(['2015-01-15', '2015-01-31', '2015-02-15', '2015-02-28'], dtype='datetime64[ns]', freq='SM-15') 

SemiMonthBegin:

In [46]: pd.Timestamp("2016-01-01") + SemiMonthBegin()
Out[46]: Timestamp('2016-01-15 00:00:00')

In [47]: pd.date_range("2015-01-01", freq="SMS", periods=4)
Out[47]: DatetimeIndex(['2015-01-01', '2015-01-15', '2015-02-01', '2015-02-15'], dtype='datetime64[ns]', freq='SMS-15') 

使用锚定后缀,您还可以指定使用月中的某一天,而不是 15 号。

In [50]: pd.date_range("2015-01-01", freq="SMS-16", periods=4)
Out[50]: DatetimeIndex(['2015-01-01', '2015-01-16', '2015-02-01', '2015-02-16'], dtype='datetime64[ns]', freq='SMS-16')

In [51]: pd.date_range("2015-01-01", freq="SM-14", periods=4)
Out[51]: DatetimeIndex(['2015-01-14', '2015-01-31', '2015-02-14', '2015-02-28'], dtype='datetime64[ns]', freq='SM-14') 
```  ### 新的索引方法

下面的方法和选项已添加到`Index`中,以使其与`Series`和`DataFrame`API 更一致。

`Index`现在支持`.where()`函数进行相同形状的索引 ([GH 13170](https://github.com/pandas-dev/pandas/issues/13170))

```py
In [48]: idx = pd.Index(["a", "b", "c"])

In [49]: idx.where([True, False, True])
Out[49]: Index(['a', None, 'c'], dtype='object') 

Index现在支持.dropna()以排除缺失值 (GH 6194)

In [50]: idx = pd.Index([1, 2, np.nan, 4])

In [51]: idx.dropna()
Out[51]: Index([1.0, 2.0, 4.0], dtype='float64') 

对于MultiIndex,默认情况下,如果任何级别缺失,则会删除值。 指定how='all'仅在所有级别都缺失时删除值。

In [52]: midx = pd.MultiIndex.from_arrays([[1, 2, np.nan, 4], [1, 2, np.nan, np.nan]])

In [53]: midx
Out[53]: 
MultiIndex([(1.0, 1.0),
 (2.0, 2.0),
 (nan, nan),
 (4.0, nan)],
 )

In [54]: midx.dropna()
Out[54]: 
MultiIndex([(1, 1),
 (2, 2)],
 )

In [55]: midx.dropna(how="all")
Out[55]: 
MultiIndex([(1, 1.0),
 (2, 2.0),
 (4, nan)],
 ) 

Index现在支持.str.extractall(),返回一个DataFrame,请参阅这里的文档 (GH 10008, GH 13156)

In [56]: idx = pd.Index(["a1a2", "b1", "c1"])

In [57]: idx.str.extractall(r"ab")
Out[57]: 
 digit
 match 
0 0         1
 1         2
1 0         1

[3 rows x 1 columns] 

Index.astype()现在接受一个可选的布尔参数copy,如果满足 dtype 的要求,则允许可选复制 (GH 13209) ### Google BigQuery 增强功能

  • read_gbq() 方法增加了dialect参数,允许用户指定使用 BigQuery 的传统 SQL 还是 BigQuery 的标准 SQL。 有关更多详细信息,请参阅文档 (GH 13615).

  • to_gbq() 方法现在允许 DataFrame 列顺序与目标表模式不同 (GH 11359). ### 细粒度的 NumPy 错误状态

以前的 pandas 版本在导入pandas时会永久性地关闭 numpy 的 ufunc 错误处理。pandas 这样做是为了消除使用 numpy ufuncs 处理缺失数据(通常表示为NaN)时会出现的警告。不幸的是,这样会消除应用程序中非 pandas 代码中出现的合法警告。从 0.19.0 开始,pandas 将使用numpy.errstate上下文管理器以更精细的方式消除这些警告,仅在 pandas 代码库中实际使用这些操作的地方周围。(GH 13109, GH 13145)

升级 pandas 后,您可能会看到您的代码发出新的RuntimeWarnings。这很可能是合法的,而且在使用以前版本的 pandas 时存在的潜在原因可能只是简单地消除了警告。在RuntimeWarning的源代码周围使用numpy.errstate来控制如何处理这些条件。 ### 方法get_dummies现在返回整数数据类���

pd.get_dummies函数现在返回编码为小整数的虚拟列,而不是浮点数。(GH 8725) 这应该提供更好的内存占用。

以前的行为:

In [1]: pd.get_dummies(['a', 'b', 'a', 'c']).dtypes

Out[1]:
a    float64
b    float64
c    float64
dtype: object 

新行为:

In [58]: pd.get_dummies(["a", "b", "a", "c"]).dtypes
Out[58]: 
a    bool
b    bool
c    bool
Length: 3, dtype: object 
```  ### 将值降级为`to_numeric`中可能的最小数据类型

`pd.to_numeric()`现在接受一个`downcast`参数,如果可能的话将数据降级为指定的最小数值数据类型。([GH 13352](https://github.com/pandas-dev/pandas/issues/13352))

```py
In [59]: s = ["1", 2, 3]

In [60]: pd.to_numeric(s, downcast="unsigned")
Out[60]: array([1, 2, 3], dtype=uint8)

In [61]: pd.to_numeric(s, downcast="integer")
Out[61]: array([1, 2, 3], dtype=int8) 
```  ### pandas 开发 API

作为未来使 pandas API 更统一和易于访问的一部分,我们创建了一个标准的 pandas 子包`pandas.api`来保存公共 API。我们首先在`pandas.api.types`中公开类型内省函数。更多子包和官方认可的 API 将在未来版本的 pandas 中发布。([GH 13147](https://github.com/pandas-dev/pandas/issues/13147), [GH 13634](https://github.com/pandas-dev/pandas/issues/13634))

以下现在是这个 API 的一部分:

```py
In [62]: import pprint

In [63]: from pandas.api import types

In [64]: funcs = [f for f in dir(types) if not f.startswith("_")]

In [65]: pprint.pprint(funcs)
['CategoricalDtype',
 'DatetimeTZDtype',
 'IntervalDtype',
 'PeriodDtype',
 'infer_dtype',
 'is_any_real_numeric_dtype',
 'is_array_like',
 'is_bool',
 'is_bool_dtype',
 'is_categorical_dtype',
 'is_complex',
 'is_complex_dtype',
 'is_datetime64_any_dtype',
 'is_datetime64_dtype',
 'is_datetime64_ns_dtype',
 'is_datetime64tz_dtype',
 'is_dict_like',
 'is_dtype_equal',
 'is_extension_array_dtype',
 'is_file_like',
 'is_float',
 'is_float_dtype',
 'is_hashable',
 'is_int64_dtype',
 'is_integer',
 'is_integer_dtype',
 'is_interval',
 'is_interval_dtype',
 'is_iterator',
 'is_list_like',
 'is_named_tuple',
 'is_number',
 'is_numeric_dtype',
 'is_object_dtype',
 'is_period_dtype',
 'is_re',
 'is_re_compilable',
 'is_scalar',
 'is_signed_integer_dtype',
 'is_sparse',
 'is_string_dtype',
 'is_timedelta64_dtype',
 'is_timedelta64_ns_dtype',
 'is_unsigned_integer_dtype',
 'pandas_dtype',
 'union_categoricals'] 

注意

从内部模块pandas.core.common调用这些函数现在会显示一个DeprecationWarning。(GH 13990) ### 其他增强功能

  • Timestamp 现在可以接受类似于datetime.datetime()的位置参数和关键字参数。(GH 10758, GH 11630)

    In [66]: pd.Timestamp(2012, 1, 1)
    Out[66]: Timestamp('2012-01-01 00:00:00')
    
    In [67]: pd.Timestamp(year=2012, month=1, day=1, hour=8, minute=30)
    Out[67]: Timestamp('2012-01-01 08:30:00') 
    
  • .resample()函数现在接受on=或level=参数,用于在日期时间列或MultiIndex级别上重新采样。(GH 13500)

    In [68]: df = pd.DataFrame(
     ....:    {"date": pd.date_range("2015-01-01", freq="W", periods=5), "a": np.arange(5)},
     ....:    index=pd.MultiIndex.from_arrays(
     ....:        [[1, 2, 3, 4, 5], pd.date_range("2015-01-01", freq="W", periods=5)],
     ....:        names=["v", "d"],
     ....:    ),
     ....: )
     ....: 
    
    In [69]: df
    Out[69]: 
     date  a
    v d 
    1 2015-01-04 2015-01-04  0
    2 2015-01-11 2015-01-11  1
    3 2015-01-18 2015-01-18  2
    4 2015-01-25 2015-01-25  3
    5 2015-02-01 2015-02-01  4
    
    [5 rows x 2 columns] 
    
    In [74]: df.resample("M", on="date")[["a"]].sum()
    Out[74]:
     a
    date
    2015-01-31  6
    2015-02-28  4
    
    [2 rows x 1 columns]
    
    In [75]: df.resample("M", level="d")[["a"]].sum()
    Out[75]:
     a
    d
    2015-01-31  6
    2015-02-28  4
    
    [2 rows x 1 columns] 
    
  • GbqConnector的.get_credentials()方法现在可以首先尝试获取应用程序默认凭据。更多细节请参阅文档(GH 13577)

  • DatetimeIndex和Timestamp的.tz_localize()方法现在具有errors关键字,因此您可以将不存在的时间戳潜在地强制转换为NaT。默认行为仍然是引发NonExistentTimeError(GH 13057)

  • .to_hdf/read_hdf()现在接受路径对象(例如pathlib.Path、py.path.local)作为文件路径(GH 11773)

  • 使用engine='python'的pd.read_csv()现在支持decimal(GH 12933)、na_filter(GH 13321)和memory_map选项(GH 13381)

  • 与 Python API 一致,pd.read_csv()现在将+inf解释为正无穷大(GH 13274)

  • pd.read_html()现在支持na_values、converters、keep_default_na选项(GH 13461)

  • Categorical.astype()现在接受一个可选的布尔参数copy,当 dtype 为分类时生效(GH 13209)

  • DataFrame现在具有.asof()方法,根据所选子集返回最后一个非 NaN 值(GH 13358)

  • 如果传入一组OrderedDict对象,DataFrame构造函数现在将尊重键的顺序(GH 13304)

  • pd.read_html()现在支持decimal选项(GH 12907)

  • Series现在具有属性.is_monotonic、.is_monotonic_increasing、.is_monotonic_decreasing,类似于Index(GH 13336)

  • DataFrame.to_sql()现在允许将单个值作为所有列的 SQL 类型(GH 11886)

  • Series.append现在支持ignore_index选项(GH 13677)

  • .to_stata()和StataWriter现在可以使用字典将列名转换为标签,将变量标签写入 Stata dta 文件(GH 13535,GH 13536)

  • .to_stata()和StataWriter现在会自动将datetime64[ns]列转换为 Stata 格式%tc,而不是引发ValueError(GH 12259)

  • 当使用 convert_categoricals=True 读取具有重复值标签的 Stata 文件时,read_stata() 和 StataReader 会提出更明确的错误消息 (GH 13923)

  • DataFrame.style 现在会渲染稀疏的 MultiIndexes (GH 11655)

  • DataFrame.style 现在会显示列级别的名称(例如 DataFrame.columns.names) (GH 13775)

  • DataFrame 已经支持根据行中的值重新排序列使用 df.sort_values(by='...', axis=1) (GH 10806)

    In [70]: df = pd.DataFrame({"A": [2, 7], "B": [3, 5], "C": [4, 8]}, index=["row1", "row2"])
    
    In [71]: df
    Out[71]: 
     A  B  C
    row1  2  3  4
    row2  7  5  8
    
    [2 rows x 3 columns]
    
    In [72]: df.sort_values(by="row2", axis=1)
    Out[72]: 
     B  A  C
    row1  3  2  4
    row2  5  7  8
    
    [2 rows x 3 columns] 
    
  • 在 I/O 文档中添加了关于读取具有混合 dtypes 的列的危险性以及如何处理的说明 (GH 13746)

  • to_html() 现在具有 border 参数来控制开放 <table> 标签中的值。默认值为 html.border 选项的值,默认为 1。这也会影响笔记本 HTML 表示,但由于 Jupyter 的 CSS 包含了一个 border-width 属性,所以视觉效果是相同的。 (GH 11563)

  • 当未安装 sqlalchemy 并使用连接字符串时,sql 函数将引发 ImportError 错误 (GH 11920)

  • 与 matplotlib 2.0 兼容。旧版本的 pandas 应该也可以与 matplotlib 2.0 一起工作 (GH 13333)

  • Timestamp, Period, DatetimeIndex, PeriodIndex 和 .dt accessor 现在具有 .is_leap_year 属性来检查日期是否属于闰年。 (GH 13727)

  • astype() 现在将接受列名到数据类型映射的字典作为 dtype 参数。 (GH 12086)

  • pd.read_json 和 DataFrame.to_json 现在支持使用 lines 选项读取和写入 json 行,参见 Line delimited json (GH 9180)

  • read_excel() 现在支持 true_values 和 false_values 关键字参数 (GH 13347)

  • groupby() 现在将接受标量和单元素列表以指定非 MultiIndex 分组器上的 level。 (GH 13907)

  • 在 excel 日期列中的不可转换日期将以 object dtype 返回,而不是引发异常 (GH 10001).

  • 现在接受pd.Timedelta(None),并将返回NaT,与pd.Timestamp相似(GH 13687)

  • pd.read_stata() 现在可以处理一些格式为 111 的文件,这些文件是由 SAS 生成 Stata dta 文件时产生的(GH 11526)

  • Series 和 Index 现在支持 divmod,将返回一个系列或索引的元组。这遵循标准的二元运算符,关于广播规则(GH 14208)的行为。 ### 函数 merge_asof 用于 asof 风格的时序连接

通过merge_asof() 函数添加了一个长期请求的功能,以支持时序数据的 asof 风格连接(GH 1870, GH 13695, GH 13709, GH 13902)。完整的文档在这里。

merge_asof() 执行 asof 合并,类似于左连接,但我们匹配最近的键,而不是相等的键。

In [1]: left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]})

In [2]: right = pd.DataFrame({"a": [1, 2, 3, 6, 7], "right_val": [1, 2, 3, 6, 7]})

In [3]: left
Out[3]: 
 a left_val
0   1        a
1   5        b
2  10        c

[3 rows x 2 columns]

In [4]: right
Out[4]: 
 a  right_val
0  1          1
1  2          2
2  3          3
3  6          6
4  7          7

[5 rows x 2 columns] 

我们通常希望尽可能精确地匹配,并在其他情况下使用最近的值。

In [5]: pd.merge_asof(left, right, on="a")
Out[5]: 
 a left_val  right_val
0   1        a          1
1   5        b          3
2  10        c          7

[3 rows x 3 columns] 

我们也可以只匹配具有先前数据的行,而不是完全匹配。

In [6]: pd.merge_asof(left, right, on="a", allow_exact_matches=False)
Out[6]: 
 a left_val  right_val
0   1        a        NaN
1   5        b        3.0
2  10        c        7.0

[3 rows x 3 columns] 

在一个典型的时间序列示例中,我们有 trades 和 quotes,我们想要对它们进行 asof-join。这也说明了在合并之前使用 by 参数对数据进行分组。

In [7]: trades = pd.DataFrame(
 ...:    {
 ...:        "time": pd.to_datetime(
 ...:            [
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.038",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.048",
 ...:            ]
 ...:        ),
 ...:        "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"],
 ...:        "price": [51.95, 51.95, 720.77, 720.92, 98.00],
 ...:        "quantity": [75, 155, 100, 100, 100],
 ...:    },
 ...:    columns=["time", "ticker", "price", "quantity"],
 ...: )
 ...: 

In [8]: quotes = pd.DataFrame(
 ...:    {
 ...:        "time": pd.to_datetime(
 ...:            [
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.023",
 ...:                "20160525 13:30:00.030",
 ...:                "20160525 13:30:00.041",
 ...:                "20160525 13:30:00.048",
 ...:                "20160525 13:30:00.049",
 ...:                "20160525 13:30:00.072",
 ...:                "20160525 13:30:00.075",
 ...:            ]
 ...:        ),
 ...:        "ticker": ["GOOG", "MSFT", "MSFT", "MSFT", "GOOG", "AAPL", "GOOG", "MSFT"],
 ...:        "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
 ...:        "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03],
 ...:    },
 ...:    columns=["time", "ticker", "bid", "ask"],
 ...: )
 ...: 
In [9]: trades
Out[9]: 
 time ticker   price  quantity
0 2016-05-25 13:30:00.023   MSFT   51.95        75
1 2016-05-25 13:30:00.038   MSFT   51.95       155
2 2016-05-25 13:30:00.048   GOOG  720.77       100
3 2016-05-25 13:30:00.048   GOOG  720.92       100
4 2016-05-25 13:30:00.048   AAPL   98.00       100

[5 rows x 4 columns]

In [10]: quotes
Out[10]: 
 time ticker     bid     ask
0 2016-05-25 13:30:00.023   GOOG  720.50  720.93
1 2016-05-25 13:30:00.023   MSFT   51.95   51.96
2 2016-05-25 13:30:00.030   MSFT   51.97   51.98
3 2016-05-25 13:30:00.041   MSFT   51.99   52.00
4 2016-05-25 13:30:00.048   GOOG  720.50  720.93
5 2016-05-25 13:30:00.049   AAPL   97.99   98.01
6 2016-05-25 13:30:00.072   GOOG  720.50  720.88
7 2016-05-25 13:30:00.075   MSFT   52.01   52.03

[8 rows x 4 columns] 

asof 合并在 on 上进行,通常是一个有序的日期时间字段,在这种情况下,我们在 by 字段中使用了一个分组器。这类似于左外连接,只是自动进行前向填充,以获取最近的非 NaN 值。

In [11]: pd.merge_asof(trades, quotes, on="time", by="ticker")
Out[11]: 
 time ticker   price  quantity     bid     ask
0 2016-05-25 13:30:00.023   MSFT   51.95        75   51.95   51.96
1 2016-05-25 13:30:00.038   MSFT   51.95       155   51.97   51.98
2 2016-05-25 13:30:00.048   GOOG  720.77       100  720.50  720.93
3 2016-05-25 13:30:00.048   GOOG  720.92       100  720.50  720.93
4 2016-05-25 13:30:00.048   AAPL   98.00       100     NaN     NaN

[5 rows x 6 columns] 

这返回一个合并的 DataFrame,其条目与原始的左侧传递的 DataFrame(在本例中是 trades)中的条目具有相同的顺序,quotes 的字段已合并。

方法 .rolling() 现在具有时间序列意识

.rolling() 对象现在具有时间序列意识,并且可以接受时间序列偏移(或可转换的)作为window 参数(GH 13327, GH 12995)。查看完整文档在这里。

In [12]: dft = pd.DataFrame(
 ....:    {"B": [0, 1, 2, np.nan, 4]},
 ....:    index=pd.date_range("20130101 09:00:00", periods=5, freq="s"),
 ....: )
 ....: 

In [13]: dft
Out[13]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  2.0
2013-01-01 09:00:03  NaN
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

这是一个常规的频率索引。使用整数窗口参数沿着窗口频率滚动。

In [14]: dft.rolling(2).sum()
Out[14]: 
 B
2013-01-01 09:00:00  NaN
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  NaN
2013-01-01 09:00:04  NaN

[5 rows x 1 columns]

In [15]: dft.rolling(2, min_periods=1).sum()
Out[15]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

指定偏移量可以更直观地指定滚动频率。

In [16]: dft.rolling("2s").sum()
Out[16]: 
 B
2013-01-01 09:00:00  0.0
2013-01-01 09:00:01  1.0
2013-01-01 09:00:02  3.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:04  4.0

[5 rows x 1 columns] 

使用非常规但仍然单调的索引,使用整数窗口进行滚动不会带来任何特殊的计算。

In [17]: dft = pd.DataFrame(
 ....:    {"B": [0, 1, 2, np.nan, 4]},
 ....:    index=pd.Index(
 ....:        [
 ....:            pd.Timestamp("20130101 09:00:00"),
 ....:            pd.Timestamp("20130101 09:00:02"),
 ....:            pd.Timestamp("20130101 09:00:03"),
 ....:            pd.Timestamp("20130101 09:00:05"),
 ....:            pd.Timestamp("20130101 09:00:06"),
 ....:        ],
 ....:        name="foo",
 ....:    ),
 ....: )
 ....: 

In [18]: dft
Out[18]: 
 B
foo 
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  2.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  4.0

[5 rows x 1 columns]

In [19]: dft.rolling(2).sum()
Out[19]: 
 B
foo 
2013-01-01 09:00:00  NaN
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  NaN

[5 rows x 1 columns] 

使用时间规范为这些稀疏数据生成可变窗口。

In [20]: dft.rolling("2s").sum()
Out[20]: 
 B
foo 
2013-01-01 09:00:00  0.0
2013-01-01 09:00:02  1.0
2013-01-01 09:00:03  3.0
2013-01-01 09:00:05  NaN
2013-01-01 09:00:06  4.0

[5 rows x 1 columns] 

此外,我们现在允许一个可选的on参数来指定 DataFrame 中的列(而不是默认的索引)。

In [21]: dft = dft.reset_index()

In [22]: dft
Out[22]: 
 foo    B
0 2013-01-01 09:00:00  0.0
1 2013-01-01 09:00:02  1.0
2 2013-01-01 09:00:03  2.0
3 2013-01-01 09:00:05  NaN
4 2013-01-01 09:00:06  4.0

[5 rows x 2 columns]

In [23]: dft.rolling("2s", on="foo").sum()
Out[23]: 
 foo    B
0 2013-01-01 09:00:00  0.0
1 2013-01-01 09:00:02  1.0
2 2013-01-01 09:00:03  3.0
3 2013-01-01 09:00:05  NaN
4 2013-01-01 09:00:06  4.0

[5 rows x 2 columns] 

方法read_csv对重复列名的支持已经改进

重复列名现在在read_csv()中得到支持,无论它们是在文件中还是作为names参数传递进来的 (GH 7160, GH 9424)

In [24]: data = "0,1,2\n3,4,5"

In [25]: names = ["a", "b", "a"] 

先前的行为:

In [2]: pd.read_csv(StringIO(data), names=names)
Out[2]:
 a  b  a
0  2  1  2
1  5  4  5 

第一个a列包含了与第二个a列相同的数据,而它应该包含值[0, 3]。

新行为:

In [26]: pd.read_csv(StringIO(data), names=names)
---------------------------------------------------------------------------
ValueError  Traceback (most recent call last)
Cell In[26], line 1
----> 1 pd.read_csv(StringIO(data), names=names)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:1026, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)
  1013 kwds_defaults = _refine_defaults_read(
  1014     dialect,
  1015     delimiter,
   (...)
  1022     dtype_backend=dtype_backend,
  1023 )
  1024 kwds.update(kwds_defaults)
-> 1026 return _read(filepath_or_buffer, kwds)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:617, in _read(filepath_or_buffer, kwds)
  614 nrows = kwds.get("nrows", None)
  616 # Check for duplicates in names.
--> 617 _validate_names(kwds.get("names", None))
  619 # Create the parser.
  620 parser = TextFileReader(filepath_or_buffer, **kwds)

File ~/work/pandas/pandas/pandas/io/parsers/readers.py:576, in _validate_names(names)
  574 if names is not None:
  575     if len(names) != len(set(names)):
--> 576         raise ValueError("Duplicate names are not allowed.")
  577     if not (
  578         is_list_like(names, allow_sets=False) or isinstance(names, abc.KeysView)
  579     ):
  580         raise ValueError("Names should be an ordered collection.")

ValueError: Duplicate names are not allowed. 

方法read_csv支持直接解析Categorical

当指定为 dtype 时,read_csv()函数现在支持解析Categorical列 (GH 10153)。根据数据的结构,这可能导致比解析后转换为Categorical更快的解析时间和更低的内存使用。请参阅 io 这里的文档。

In [27]: data = """
 ....: col1,col2,col3
 ....: a,b,1
 ....: a,b,2
 ....: c,d,3
 ....: """
 ....: 

In [28]: pd.read_csv(StringIO(data))
Out[28]: 
 col1 col2  col3
0    a    b     1
1    a    b     2
2    c    d     3

[3 rows x 3 columns]

In [29]: pd.read_csv(StringIO(data)).dtypes
Out[29]: 
col1    object
col2    object
col3     int64
Length: 3, dtype: object

In [30]: pd.read_csv(StringIO(data), dtype="category").dtypes
Out[30]: 
col1    category
col2    category
col3    category
Length: 3, dtype: object 

可以使用字典规范将单独的列解析为Categorical

In [31]: pd.read_csv(StringIO(data), dtype={"col1": "category"}).dtypes
Out[31]: 
col1    category
col2      object
col3       int64
Length: 3, dtype: object 

注意

结果类别将始终被解析为字符串(object dtype)。如果类别是数字的,可以使用to_numeric()函数进行转换,或者根据需要使用另一个转换器,如to_datetime()。

In [32]: df = pd.read_csv(StringIO(data), dtype="category")

In [33]: df.dtypes
Out[33]: 
col1    category
col2    category
col3    category
Length: 3, dtype: object

In [34]: df["col3"]
Out[34]: 
0    1
1    2
2    3
Name: col3, Length: 3, dtype: category
Categories (3, object): ['1', '2', '3']

In [35]: new_categories = pd.to_numeric(df["col3"].cat.categories)

In [36]: df["col3"] = df["col3"].cat.rename_categories(new_categories)

In [37]: df["col3"]
Out[37]: 
0    1
1    2
2    3
Name: col3, Length: 3, dtype: category
Categories (3, int64): [1, 2, 3] 

分类合并

  • 添加了一个函数union_categoricals()用于合并分类变量,参见 Unioning Categoricals (GH 13361, GH 13763, GH 13846, GH 14173)

    In [38]: from pandas.api.types import union_categoricals
    
    In [39]: a = pd.Categorical(["b", "c"])
    
    In [40]: b = pd.Categorical(["a", "b"])
    
    In [41]: union_categoricals([a, b])
    Out[41]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['b', 'c', 'a'] 
    
  • concat和append现在可以将具有不同categories的category dtypes 连接为object dtype (GH 13524)

    In [42]: s1 = pd.Series(["a", "b"], dtype="category")
    
    In [43]: s2 = pd.Series(["b", "c"], dtype="category") 
    

先前的行为:

In [1]: pd.concat([s1, s2])
ValueError: incompatible categories in categorical concat 

新行为:

In [44]: pd.concat([s1, s2])
Out[44]: 
0    a
1    b
0    b
1    c
Length: 4, dtype: object 

半月偏移

pandas 新增了新的频率偏移,SemiMonthEnd(‘SM’)和SemiMonthBegin(‘SMS’)。这些提供的日期偏移默认锚定在月中(15 号)和月末,以及月中(15 号)和月初(1 号)。(GH 1543)

In [45]: from pandas.tseries.offsets import SemiMonthEnd, SemiMonthBegin 

SemiMonthEnd:

In [46]: pd.Timestamp("2016-01-01") + SemiMonthEnd()
Out[46]: Timestamp('2016-01-15 00:00:00')

In [47]: pd.date_range("2015-01-01", freq="SM", periods=4)
Out[47]: DatetimeIndex(['2015-01-15', '2015-01-31', '2015-02-15', '2015-02-28'], dtype='datetime64[ns]', freq='SM-15') 

SemiMonthBegin:

In [46]: pd.Timestamp("2016-01-01") + SemiMonthBegin()
Out[46]: Timestamp('2016-01-15 00:00:00')

In [47]: pd.date_range("2015-01-01", freq="SMS", periods=4)
Out[47]: DatetimeIndex(['2015-01-01', '2015-01-15', '2015-02-01', '2015-02-15'], dtype='datetime64[ns]', freq='SMS-15') 

使用锚定后缀,您还可以指定要使用的月份的日期,而不是 15 号。

In [50]: pd.date_range("2015-01-01", freq="SMS-16", periods=4)
Out[50]: DatetimeIndex(['2015-01-01', '2015-01-16', '2015-02-01', '2015-02-16'], dtype='datetime64[ns]', freq='SMS-16')

In [51]: pd.date_range("2015-01-01", freq="SM-14", periods=4)
Out[51]: DatetimeIndex(['2015-01-14', '2015-01-31', '2015-02-14', '2015-02-28'], dtype='datetime64[ns]', freq='SM-14') 

新的 Index 方法

下面的方法和选项已添加到Index中,以使其与Series和DataFrameAPI 更加一致。

Index 现在支持 .where() 函数进行相同形状的索引(GH 13170)。

In [48]: idx = pd.Index(["a", "b", "c"])

In [49]: idx.where([True, False, True])
Out[49]: Index(['a', None, 'c'], dtype='object') 

Index 现在支持 .dropna() 以排除缺失值(GH 6194)。

In [50]: idx = pd.Index([1, 2, np.nan, 4])

In [51]: idx.dropna()
Out[51]: Index([1.0, 2.0, 4.0], dtype='float64') 

对于 MultiIndex,默认情况下如果任何级别缺失,则会删除值。指定 how='all' 仅删除所有级别都缺失的值。

In [52]: midx = pd.MultiIndex.from_arrays([[1, 2, np.nan, 4], [1, 2, np.nan, np.nan]])

In [53]: midx
Out[53]: 
MultiIndex([(1.0, 1.0),
 (2.0, 2.0),
 (nan, nan),
 (4.0, nan)],
 )

In [54]: midx.dropna()
Out[54]: 
MultiIndex([(1, 1),
 (2, 2)],
 )

In [55]: midx.dropna(how="all")
Out[55]: 
MultiIndex([(1, 1.0),
 (2, 2.0),
 (4, nan)],
 ) 

Index 现在支持 .str.extractall(),它返回一个 DataFrame,请参阅此处的文档(GH 10008,GH 13156)

In [56]: idx = pd.Index(["a1a2", "b1", "c1"])

In [57]: idx.str.extractall(r"ab")
Out[57]: 
 digit
 match 
0 0         1
 1         2
1 0         1

[3 rows x 1 columns] 

Index.astype() 现在接受一个可选的布尔参数 copy,如果满足 dtype 的要求,则允许可选复制(GH 13209)。

Google BigQuery 增强

  • read_gbq() 方法增加了 dialect 参数,允许用户指定使用 BigQuery 的传统 SQL 还是标准 SQL。更多细节请参阅文档(GH 13615)。

  • to_gbq() 方法现在允许 DataFrame 的列顺序与目标表模式不同(GH 11359)。

细粒度的 NumPy errstate

先前版本的 pandas 在导入时永久消除了 numpy 的 ufunc 错误处理。pandas 这样做是为了消除在缺失数据上使用 numpy ufuncs 时可能引发的警告,这些警告通常表示为 NaN。不幸的是,这样做会消除应用程序中非 pandas 代码中出现的合法警告。从 0.19.0 开始,pandas 将使用 numpy.errstate 上下文管理器以更精细的方式消除这些警告,仅在 pandas 代码库中实际使用这些操作的地方周围使用。 (GH 13109,GH 13145)

升级 pandas 后,您可能会看到来自您的代码发出的 新 RuntimeWarnings。这些可能是合法的,并且在使用先前版本的 pandas 时存在于代码中的潜在原因很可能是在代码中简单地消除了警告。在 RuntimeWarning 的源头周围使用 numpy.errstate 来控制这些条件的处理。

方法 get_dummies 现在返回整数 dtype

pd.get_dummies 函数现在将虚拟编码列返回为小整数,而不是浮点数(GH 8725)。这应该提供了更好的内存占用。

先前行为:

In [1]: pd.get_dummies(['a', 'b', 'a', 'c']).dtypes

Out[1]:
a    float64
b    float64
c    float64
dtype: object 

新行为:

In [58]: pd.get_dummies(["a", "b", "a", "c"]).dtypes
Out[58]: 
a    bool
b    bool
c    bool
Length: 3, dtype: object 

在 to_numeric 中将值降级为最小可能的数据类型

pd.to_numeric() 现在接受一个 downcast 参数,如果可能的话,将数据降级为指定的最小数值数据类型 (GH 13352)。

In [59]: s = ["1", 2, 3]

In [60]: pd.to_numeric(s, downcast="unsigned")
Out[60]: array([1, 2, 3], dtype=uint8)

In [61]: pd.to_numeric(s, downcast="integer")
Out[61]: array([1, 2, 3], dtype=int8) 

pandas 开发 API

作为使 pandas API 在未来更加统一和易于访问的一部分,我们创建了一个标准的 pandas 子包 pandas.api 来保存公共 API。我们首先在 pandas.api.types 中公开了类型内省函数。未来版本的 pandas 将发布更多的子包和官方认可的 API (GH 13147, GH 13634)。

以下内容现已成为此 API 的一部分:

In [62]: import pprint

In [63]: from pandas.api import types

In [64]: funcs = [f for f in dir(types) if not f.startswith("_")]

In [65]: pprint.pprint(funcs)
['CategoricalDtype',
 'DatetimeTZDtype',
 'IntervalDtype',
 'PeriodDtype',
 'infer_dtype',
 'is_any_real_numeric_dtype',
 'is_array_like',
 'is_bool',
 'is_bool_dtype',
 'is_categorical_dtype',
 'is_complex',
 'is_complex_dtype',
 'is_datetime64_any_dtype',
 'is_datetime64_dtype',
 'is_datetime64_ns_dtype',
 'is_datetime64tz_dtype',
 'is_dict_like',
 'is_dtype_equal',
 'is_extension_array_dtype',
 'is_file_like',
 'is_float',
 'is_float_dtype',
 'is_hashable',
 'is_int64_dtype',
 'is_integer',
 'is_integer_dtype',
 'is_interval',
 'is_interval_dtype',
 'is_iterator',
 'is_list_like',
 'is_named_tuple',
 'is_number',
 'is_numeric_dtype',
 'is_object_dtype',
 'is_period_dtype',
 'is_re',
 'is_re_compilable',
 'is_scalar',
 'is_signed_integer_dtype',
 'is_sparse',
 'is_string_dtype',
 'is_timedelta64_dtype',
 'is_timedelta64_ns_dtype',
 'is_unsigned_integer_dtype',
 'pandas_dtype',
 'union_categoricals'] 

注意

从内部模块 pandas.core.common 调用这些函数现在将显示一个 DeprecationWarning (GH 13990)。

其他增强功能

  • Timestamp 现在可以接受类似于 datetime.datetime() 的位置参数和关键字参数 (GH 10758, GH 11630)。

    In [66]: pd.Timestamp(2012, 1, 1)
    Out[66]: Timestamp('2012-01-01 00:00:00')
    
    In [67]: pd.Timestamp(year=2012, month=1, day=1, hour=8, minute=30)
    Out[67]: Timestamp('2012-01-01 08:30:00') 
    
  • .resample() 函数现在接受 on= 或 level= 参数,用于在日期时间列或 MultiIndex 级别上重新采样 (GH 13500)。

    In [68]: df = pd.DataFrame(
     ....:    {"date": pd.date_range("2015-01-01", freq="W", periods=5), "a": np.arange(5)},
     ....:    index=pd.MultiIndex.from_arrays(
     ....:        [[1, 2, 3, 4, 5], pd.date_range("2015-01-01", freq="W", periods=5)],
     ....:        names=["v", "d"],
     ....:    ),
     ....: )
     ....: 
    
    In [69]: df
    Out[69]: 
     date  a
    v d 
    1 2015-01-04 2015-01-04  0
    2 2015-01-11 2015-01-11  1
    3 2015-01-18 2015-01-18  2
    4 2015-01-25 2015-01-25  3
    5 2015-02-01 2015-02-01  4
    
    [5 rows x 2 columns] 
    
    In [74]: df.resample("M", on="date")[["a"]].sum()
    Out[74]:
     a
    date
    2015-01-31  6
    2015-02-28  4
    
    [2 rows x 1 columns]
    
    In [75]: df.resample("M", level="d")[["a"]].sum()
    Out[75]:
     a
    d
    2015-01-31  6
    2015-02-28  4
    
    [2 rows x 1 columns] 
    
  • GbqConnector 的 .get_credentials() 方法现在可以首先尝试获取应用程序默认凭据。更多详细信息请参阅文档 (GH 13577)。

  • DatetimeIndex 和 Timestamp 的 .tz_localize() 方法现已增加了 errors 关键字,因此您可以将不存在的时间戳潜在地强制转换为 NaT。默认行为仍然是引发 NonExistentTimeError (GH 13057)。

  • .to_hdf/read_hdf() 现在接受路径对象(例如 pathlib.Path,py.path.local)作为文件路径 (GH 11773)。

  • pd.read_csv() 使用 engine='python' 现已支持 decimal (GH 12933),na_filter (GH 13321) 和 memory_map 选项 (GH 13381)。

  • 与 Python API 一致,pd.read_csv() 现在将 +inf 解释为正无穷大 (GH 13274)。

  • pd.read_html() 现已支持 na_values,converters,keep_default_na 选项 (GH 13461)。

  • Categorical.astype() 现在接受一个可选的布尔参数 copy,在 dtype 为 categorical 时有效 (GH 13209)。

  • DataFrame已经增加了.asof()方法,以根据所选子集返回最后一个非 NaN 值(GH 13358)。

  • 如果传递了OrderedDict对象列表,则DataFrame构造函数现在将尊重键排序(GH 13304)。

  • pd.read_html()现在支持decimal选项(GH 12907)。

  • Series已经增加了.is_monotonic、.is_monotonic_increasing、.is_monotonic_decreasing属性,类似于Index(GH 13336)。

  • DataFrame.to_sql()现在允许将单个值用作所有列的 SQL 类型(GH 11886)。

  • Series.append现在支持ignore_index选项(GH 13677)。

  • .to_stata()和StataWriter现在可以使用字典将列名转换为标签,将变量标签写入 Stata dta 文件(GH 13535, GH 13536)。

  • .to_stata()和StataWriter现在将自动将datetime64[ns]列转换为 Stata 格式%tc,而不是引发ValueError(GH 12259)。

  • 当使用convert_categoricals=True时,read_stata()和StataReader在读取具有重复值标签的 Stata 文件时会引发一个更明确的错误消息(GH 13923)。

  • DataFrame.style现在将呈现稀疏化的 MultiIndexes(GH 11655)。

  • DataFrame.style现在将显示列级别的名称(例如DataFrame.columns.names)(GH 13775)。

  • DataFrame已经增加了根据行中的值重新排序列的支持,使用df.sort_values(by='...', axis=1)(GH 10806)。

    In [70]: df = pd.DataFrame({"A": [2, 7], "B": [3, 5], "C": [4, 8]}, index=["row1", "row2"])
    
    In [71]: df
    Out[71]: 
     A  B  C
    row1  2  3  4
    row2  7  5  8
    
    [2 rows x 3 columns]
    
    In [72]: df.sort_values(by="row2", axis=1)
    Out[72]: 
     B  A  C
    row1  3  2  4
    row2  5  7  8
    
    [2 rows x 3 columns] 
    
  • 添加了关于在读取具有混合数据类型列时可能遇到的问题以及如何处理的 I/O 文档(GH 13746)。

  • to_html()现在具有一个border参数,用于控制在开放的<table>标签中的值。默认值是html.border选项的值,默认为 1。这也会影响到笔记本的 HTML 表示,但由于 Jupyter 的 CSS 包含了一个 border-width 属性,视觉效果是一样的。(GH 11563).

  • 当未安装sqlalchemy并且使用连接字符串时,在 sql 函数中引发ImportError(GH 11920)。

  • 与 matplotlib 2.0 兼容。较旧版本的 pandas 应该也可以与 matplotlib 2.0 兼容。(GH 13333)

  • Timestamp、Period、DatetimeIndex、PeriodIndex 和 .dt 访问器现已新增 .is_leap_year 属性,用于检查日期是否属于闰年。(GH 13727)

  • astype() 现在接受将列名映射到数据类型的字典作为 dtype 参数。(GH 12086)

  • pd.read_json 和 DataFrame.to_json 现已支持使用 lines 选项读取和写入行分隔的 json,请参阅 行分隔的 json。(GH 9180)

  • read_excel() 现在支持 true_values 和 false_values 关键字参数。(GH 13347)

  • groupby() 现在接受标量和单元素列表来指定非MultiIndex分组器上的 level。(GH 13907)

  • 在 Excel 日期列中,不可转换的日期将不进行转换,并且列将是 object 数据类型,而不是引发异常。(GH 10001)

  • pd.Timedelta(None) 现在被接受,并将返回 NaT,与 pd.Timestamp 类似。(GH 13687)

  • pd.read_stata() 现在可以处理由 SAS 生成 Stata dta 文件时产生的一些格式为 111 的文件。(GH 11526)

  • Series 和 Index 现在支持 divmod,将返回系列或索引的元组。这与广播规则一致的标准二元运算符行为。(GH 14208)

API 更改

Series.tolist() 现在将返回 Python 类型

Series.tolist() 现在将在输出中返回 Python 类型,模仿 NumPy 的 .tolist() 行为。(GH 10904)

In [73]: s = pd.Series([1, 2, 3]) 

之前的行为:

In [7]: type(s.tolist()[0])
Out[7]:
 <class 'numpy.int64'> 

新行为:

In [74]: type(s.tolist()[0])
Out[74]: int 

不同索引的 Series 运算符

以下 Series 运算符已更改,使所有运算符保持一致,包括 DataFrame。(GH 1134, GH 4581, GH 13538)

  • 当 index 不同时,Series 比较运算符现在会引发 ValueError。

  • Series 逻辑运算符会对左右手边的 index 进行对齐。

警告

直到 0.18.1,比较具有相同长度的Series,即使.index不同也会成功(结果忽略.index)。从 0.19.0 开始,这将引发ValueError以更加严格。本节还描述了如何保持先前行为或对齐不同索引,使用像.eq这样的灵活比较方法。

因此,Series和DataFrame的运算符行为如下:

算术运算符

算术运算符会对齐两个index(无更改)。

In [75]: s1 = pd.Series([1, 2, 3], index=list("ABC"))

In [76]: s2 = pd.Series([2, 2, 2], index=list("ABD"))

In [77]: s1 + s2
Out[77]: 
A    3.0
B    4.0
C    NaN
D    NaN
Length: 4, dtype: float64

In [78]: df1 = pd.DataFrame([1, 2, 3], index=list("ABC"))

In [79]: df2 = pd.DataFrame([2, 2, 2], index=list("ABD"))

In [80]: df1 + df2
Out[80]: 
 0
A  3.0
B  4.0
C  NaN
D  NaN

[4 rows x 1 columns] 

比较运算符

当.index不同时,比较运算符会引发ValueError。

先前行为(Series):

Series比较值时会忽略.index,只要两者长度相同:

In [1]: s1 == s2
Out[1]:
A    False
B     True
C    False
dtype: bool 

新行为(Series):

In [2]: s1 == s2
Out[2]:
ValueError: Can only compare identically-labeled Series objects 

注意

要实现与先前版本相同的结果(基于位置比较值而忽略.index),请比较.values。

In [81]: s1.values == s2.values
Out[81]: array([False,  True, False]) 

如果要比较Series并对齐其.index,请参见下面的灵活比较方法部分:

In [82]: s1.eq(s2)
Out[82]: 
A    False
B     True
C    False
D    False
Length: 4, dtype: bool 

当前行为(DataFrame,无更改):

In [3]: df1 == df2
Out[3]:
ValueError: Can only compare identically-labeled DataFrame objects 

逻辑运算符

逻辑运算符会对齐左右两侧的.index。

先前行为(Series),仅保留左侧的index:

In [4]: s1 = pd.Series([True, False, True], index=list('ABC'))
In [5]: s2 = pd.Series([True, True, True], index=list('ABD'))
In [6]: s1 & s2
Out[6]:
A     True
B    False
C    False
dtype: bool 

新行为(Series):

In [83]: s1 = pd.Series([True, False, True], index=list("ABC"))

In [84]: s2 = pd.Series([True, True, True], index=list("ABD"))

In [85]: s1 & s2
Out[85]: 
A     True
B    False
C    False
D    False
Length: 4, dtype: bool 

注意

Series逻辑运算符将NaN结果填充为False。

注意

要实现与先前版本相同的结果(仅基于左侧索引比较值),可以使用reindex_like:

In [86]: s1 & s2.reindex_like(s1)
Out[86]: 
A     True
B    False
C    False
Length: 3, dtype: bool 

当前行为(DataFrame,无更改):

In [87]: df1 = pd.DataFrame([True, False, True], index=list("ABC"))

In [88]: df2 = pd.DataFrame([True, True, True], index=list("ABD"))

In [89]: df1 & df2
Out[89]: 
 0
A   True
B  False
C  False
D  False

[4 rows x 1 columns] 

灵活的比较方法

Series的灵活比较方法如eq、ne、le、lt、ge和gt现在会对齐两个index。如果要比较具有不同index的两个Series,请使用这些运算符。

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

In [91]: s2 = pd.Series([2, 2, 2], index=["b", "c", "d"])

In [92]: s1.eq(s2)
Out[92]: 
a    False
b     True
c    False
d    False
Length: 4, dtype: bool

In [93]: s1.ge(s2)
Out[93]: 
a    False
b     True
c     True
d    False
Length: 4, dtype: bool 

以前,这与比较运算符的行为相同(见上文)。### Series类型在赋值时的提升

Series现在将正确提升其数据类型以与当前数据类型不兼容的值进行赋值(GH 13234)

In [94]: s = pd.Series() 

先前行为:

In [2]: s["a"] = pd.Timestamp("2016-01-01")

In [3]: s["b"] = 3.0
TypeError: invalid type promotion 

新行为:

In [95]: s["a"] = pd.Timestamp("2016-01-01")

In [96]: s["b"] = 3.0

In [97]: s
Out[97]: 
a    2016-01-01 00:00:00
b                    3.0
Length: 2, dtype: object

In [98]: s.dtype
Out[98]: dtype('O') 
```  ### 函数`.to_datetime()`的更改

以前,如果`.to_datetime()`遇到混合整数/浮点数和字符串,但没有日期时间且`errors='coerce'`,它会将所有内容转换为`NaT`。

**先前行为**:

```py
In [2]: pd.to_datetime([1, 'foo'], errors='coerce')
Out[2]: DatetimeIndex(['NaT', 'NaT'], dtype='datetime64[ns]', freq=None) 

当前行为:

现在将整数/浮点数转换为默认单位为ns。

In [99]: pd.to_datetime([1, "foo"], errors="coerce")
Out[99]: DatetimeIndex(['1970-01-01 00:00:00.000000001', 'NaT'], dtype='datetime64[ns]', freq=None) 

与.to_datetime()相关的错误修复:

  • 修复了pd.to_datetime()在传递整数或浮点数时,没有unit和errors='coerce'时的错误(GH 13180)。

  • 修复了pd.to_datetime()在传递无效数据类型(例如布尔值)时的错误;现在将尊重errors关键字(GH 13176)

  • 修复了pd.to_datetime()在int8和int16数据类型上溢出的错误(GH 13451)

  • 修复了pd.to_datetime()在errors='ignore'时,NaN和另一个字符串无效时引发AttributeError的错误(GH 12424)

  • pd.to_datetime()中的错误,当指定了unit时,没有正确地转换浮点数,导致截断的 datetime(GH 13834) ### 合并变更

合并现在将保留连接键的 dtype(GH 8596)

In [100]: df1 = pd.DataFrame({"key": [1], "v1": [10]})

In [101]: df1
Out[101]: 
 key  v1
0    1  10

[1 rows x 2 columns]

In [102]: df2 = pd.DataFrame({"key": [1, 2], "v1": [20, 30]})

In [103]: df2
Out[103]: 
 key  v1
0    1  20
1    2  30

[2 rows x 2 columns] 

以前的行为:

In [5]: pd.merge(df1, df2, how='outer')
Out[5]:
 key    v1
0  1.0  10.0
1  1.0  20.0
2  2.0  30.0

In [6]: pd.merge(df1, df2, how='outer').dtypes
Out[6]:
key    float64
v1     float64
dtype: object 

新行为:

我们能够保留连接键

In [104]: pd.merge(df1, df2, how="outer")
Out[104]: 
 key  v1
0    1  10
1    1  20
2    2  30

[3 rows x 2 columns]

In [105]: pd.merge(df1, df2, how="outer").dtypes
Out[105]: 
key    int64
v1     int64
Length: 2, dtype: object 

当然,如果引入了缺失值,那么结果的 dtype 将被提升,这与以前的情况相同。

In [106]: pd.merge(df1, df2, how="outer", on="key")
Out[106]: 
 key  v1_x  v1_y
0    1  10.0    20
1    2   NaN    30

[2 rows x 3 columns]

In [107]: pd.merge(df1, df2, how="outer", on="key").dtypes
Out[107]: 
key       int64
v1_x    float64
v1_y      int64
Length: 3, dtype: object 
```  ### 方法`.describe()`变更

`.describe()`输出中索引中的百分位数标识符现在将舍入到最少保持它们不同的精度([GH 13104](https://github.com/pandas-dev/pandas/issues/13104))

```py
In [108]: s = pd.Series([0, 1, 2, 3, 4])

In [109]: df = pd.DataFrame([0, 1, 2, 3, 4]) 

以前的行为:

百分位数最多舍入到一位小数,如果数据框中的百分位数重复,则可能引发ValueError。

In [3]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[3]:
count     5.000000
mean      2.000000
std       1.581139
min       0.000000
0.0%      0.000400
0.1%      0.002000
0.1%      0.004000
50%       2.000000
99.9%     3.996000
100.0%    3.998000
100.0%    3.999600
max       4.000000
dtype: float64

In [4]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[4]:
...
ValueError: cannot reindex from a duplicate axis 

新行为:

In [110]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[110]: 
count     5.000000
mean      2.000000
std       1.581139
min       0.000000
0.01%     0.000400
0.05%     0.002000
0.1%      0.004000
50%       2.000000
99.9%     3.996000
99.95%    3.998000
99.99%    3.999600
max       4.000000
Length: 12, dtype: float64

In [111]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[111]: 
 0
count   5.000000
mean    2.000000
std     1.581139
min     0.000000
0.01%   0.000400
0.05%   0.002000
0.1%    0.004000
50%     2.000000
99.9%   3.996000
99.95%  3.998000
99.99%  3.999600
max     4.000000

[12 rows x 1 columns] 

此外:

  • 传递重复的percentiles现在将引发ValueError。

  • 在具有混合 dtype 列索引的 DataFrame 上的.describe()中存在错误,以前会引发TypeError(GH 13288) ### Period变更

PeriodIndex现在具有period dtype

PeriodIndex现在有自己的period dtype。period dtype 是 pandas 的扩展 dtype,类似于category或时区感知 dtype(datetime64[ns, tz])(GH 13941)。由于这一变化,PeriodIndex不再具有整数 dtype:

以前的行为:

In [1]: pi = pd.PeriodIndex(['2016-08-01'], freq='D')

In [2]: pi
Out[2]: PeriodIndex(['2016-08-01'], dtype='int64', freq='D')

In [3]: pd.api.types.is_integer_dtype(pi)
Out[3]: True

In [4]: pi.dtype
Out[4]: dtype('int64') 

新行为:

In [112]: pi = pd.PeriodIndex(["2016-08-01"], freq="D")

In [113]: pi
Out[113]: PeriodIndex(['2016-08-01'], dtype='period[D]')

In [114]: pd.api.types.is_integer_dtype(pi)
Out[114]: False

In [115]: pd.api.types.is_period_dtype(pi)
Out[115]: True

In [116]: pi.dtype
Out[116]: period[D]

In [117]: type(pi.dtype)
Out[117]: pandas.core.dtypes.dtypes.PeriodDtype 

Period('NaT')现在返回pd.NaT

以前,Period有自己的Period('NaT')表示形式,与pd.NaT不同。现在Period('NaT')已更改为返回pd.NaT。 (GH 12759,GH 13582)

以前的行为:

In [5]: pd.Period('NaT', freq='D')
Out[5]: Period('NaT', 'D') 

新行为:

这些结果在不提供freq选项的情况下产生pd.NaT。

In [118]: pd.Period("NaT")
Out[118]: NaT

In [119]: pd.Period(None)
Out[119]: NaT 

为了与Period的加法和减法兼容,pd.NaT现在支持与int的加法和减法。以前会引发ValueError。

以前的行为:

In [5]: pd.NaT + 1
...
ValueError: Cannot add integral value to Timestamp without freq. 

新行为:

In [120]: pd.NaT + 1
Out[120]: NaT

In [121]: pd.NaT - 1
Out[121]: NaT 

PeriodIndex.values现在返回Period对象的数组

.values已更改为返回Period对象的数组,而不是整数的数组(GH 13988)。

以前的行为:

In [6]: pi = pd.PeriodIndex(['2011-01', '2011-02'], freq='M')
In [7]: pi.values
Out[7]: array([492, 493]) 

新行为:

In [122]: pi = pd.PeriodIndex(["2011-01", "2011-02"], freq="M")

In [123]: pi.values
Out[123]: array([Period('2011-01', 'M'), Period('2011-02', 'M')], dtype=object) 
```  ### 索引`+` / `-`不再用于集合操作

基本 Index 类型和 DatetimeIndex(而不是数值索引类型)的加法和减法以前执行集合操作(集合并和差)。此行为自 0.15.0 版本起已被弃用(推荐使用特定的 `.union()` 和 `.difference()` 方法),现已禁用。在可能的情况下,`+` 和 `-` 现在用于逐元素操作,例如连接字符串或减去日期时间 ([GH 8227](https://github.com/pandas-dev/pandas/issues/8227), [GH 14127](https://github.com/pandas-dev/pandas/issues/14127))。

先前行为:

```py
In [1]: pd.Index(['a', 'b']) + pd.Index(['a', 'c'])
FutureWarning: using '+' to provide set union with Indexes is deprecated, use '|' or .union()
Out[1]: Index(['a', 'b', 'c'], dtype='object') 

新行为: 相同操作现在将执行逐元素加法:

In [124]: pd.Index(["a", "b"]) + pd.Index(["a", "c"])
Out[124]: Index(['aa', 'bc'], dtype='object') 

请注意,数值 Index 对象已执行逐元素操作。例如,添加两个整数索引的行为未更改。基本 Index 现在与此行为保持一致。

In [125]: pd.Index([1, 2, 3]) + pd.Index([2, 3, 4])
Out[125]: Index([3, 5, 7], dtype='int64') 

此外,由于这一变化,现在可以对两个 DatetimeIndex 对象进行减法运算,结果为 TimedeltaIndex:

先前行为:

In [1]: (pd.DatetimeIndex(['2016-01-01', '2016-01-02'])
 ...: - pd.DatetimeIndex(['2016-01-02', '2016-01-03']))
FutureWarning: using '-' to provide set differences with datetimelike Indexes is deprecated, use .difference()
Out[1]: DatetimeIndex(['2016-01-01'], dtype='datetime64[ns]', freq=None) 

新行为:

In [126]: (
 .....:    pd.DatetimeIndex(["2016-01-01", "2016-01-02"])
 .....:    - pd.DatetimeIndex(["2016-01-02", "2016-01-03"])
 .....: )
 .....: 
Out[126]: TimedeltaIndex(['-1 days', '-1 days'], dtype='timedelta64[ns]', freq=None) 
```  ### `Index.difference` 和 `.symmetric_difference` 更改

`Index.difference` 和 `Index.symmetric_difference` 现在将更一致地将 `NaN` 值视为任何其他值。([GH 13514](https://github.com/pandas-dev/pandas/issues/13514))

```py
In [127]: idx1 = pd.Index([1, 2, 3, np.nan])

In [128]: idx2 = pd.Index([0, 1, np.nan]) 

先前行为:

In [3]: idx1.difference(idx2)
Out[3]: Float64Index([nan, 2.0, 3.0], dtype='float64')

In [4]: idx1.symmetric_difference(idx2)
Out[4]: Float64Index([0.0, nan, 2.0, 3.0], dtype='float64') 

新行为:

In [129]: idx1.difference(idx2)
Out[129]: Index([2.0, 3.0], dtype='float64')

In [130]: idx1.symmetric_difference(idx2)
Out[130]: Index([0.0, 2.0, 3.0], dtype='float64') 
```  ### `Index.unique` 一致地返回 `Index`

`Index.unique()` 现在返回适当 `dtype` 的唯一值作为 `Index`。([GH 13395](https://github.com/pandas-dev/pandas/issues/13395))。以前,大多数 `Index` 类返回 `np.ndarray`,而 `DatetimeIndex`、`TimedeltaIndex` 和 `PeriodIndex` 返回 `Index` 以保留元数据,如时区。

**先前行为**:

```py
In [1]: pd.Index([1, 2, 3]).unique()
Out[1]: array([1, 2, 3])

In [2]: pd.DatetimeIndex(['2011-01-01', '2011-01-02',
 ...:                  '2011-01-03'], tz='Asia/Tokyo').unique()
Out[2]:
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
 '2011-01-03 00:00:00+09:00'],
 dtype='datetime64[ns, Asia/Tokyo]', freq=None) 

新行为:

In [131]: pd.Index([1, 2, 3]).unique()
Out[131]: Index([1, 2, 3], dtype='int64')

In [132]: pd.DatetimeIndex(
 .....:    ["2011-01-01", "2011-01-02", "2011-01-03"], tz="Asia/Tokyo"
 .....: ).unique()
 .....: 
Out[132]: 
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
 '2011-01-03 00:00:00+09:00'],
 dtype='datetime64[ns, Asia/Tokyo]', freq=None) 
```  ### `MultiIndex` 构造函数,`groupby` 和 `set_index` 保留分类 dtype

`MultiIndex.from_arrays` 和 `MultiIndex.from_product` 现在将在 `MultiIndex` 级别中保留分类 dtype ([GH 13743](https://github.com/pandas-dev/pandas/issues/13743), [GH 13854](https://github.com/pandas-dev/pandas/issues/13854)).

```py
In [133]: cat = pd.Categorical(["a", "b"], categories=list("bac"))

In [134]: lvl1 = ["foo", "bar"]

In [135]: midx = pd.MultiIndex.from_arrays([cat, lvl1])

In [136]: midx
Out[136]: 
MultiIndex([('a', 'foo'),
 ('b', 'bar')],
 ) 

先前行为:

In [4]: midx.levels[0]
Out[4]: Index(['b', 'a', 'c'], dtype='object')

In [5]: midx.get_level_values[0]
Out[5]: Index(['a', 'b'], dtype='object') 

新行为: 单级现在是 CategoricalIndex:

In [137]: midx.levels[0]
Out[137]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category')

In [138]: midx.get_level_values(0)
Out[138]: CategoricalIndex(['a', 'b'], categories=['b', 'a', 'c'], ordered=False, dtype='category') 

对 MultiIndex.from_product 进行了类似的更改。因此,groupby 和 set_index 也在索引中保留了分类 dtype

In [139]: df = pd.DataFrame({"A": [0, 1], "B": [10, 11], "C": cat})

In [140]: df_grouped = df.groupby(by=["A", "C"], observed=False).first()

In [141]: df_set_idx = df.set_index(["A", "C"]) 

先前行为:

In [11]: df_grouped.index.levels[1]
Out[11]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [12]: df_grouped.reset_index().dtypes
Out[12]:
A      int64
C     object
B    float64
dtype: object

In [13]: df_set_idx.index.levels[1]
Out[13]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [14]: df_set_idx.reset_index().dtypes
Out[14]:
A      int64
C     object
B      int64
dtype: object 

新行为:

In [142]: df_grouped.index.levels[1]
Out[142]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')

In [143]: df_grouped.reset_index().dtypes
Out[143]: 
A       int64
C    category
B     float64
Length: 3, dtype: object

In [144]: df_set_idx.index.levels[1]
Out[144]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')

In [145]: df_set_idx.reset_index().dtypes
Out[145]: 
A       int64
C    category
B       int64
Length: 3, dtype: object 
```  ### 函数 `read_csv` 将逐步枚举块

当使用`chunksize=n`调用`read_csv()`,且没有指定索引时,每个块以前都会有独立生成的索引,从`0`到`n-1`。现在,它们被赋予递进的索引,从第一个块开始为`0`,第二个块为`n`,依此类推,以便在连接时与没有`chunksize=`参数调用`read_csv()`的结果相同([GH 12185](https://github.com/pandas-dev/pandas/issues/12185))。

```py
In [146]: data = "A,B\n0,1\n2,3\n4,5\n6,7" 

之前的行为:

In [2]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[2]:
 A  B
0  0  1
1  2  3
0  4  5
1  6  7 

新的行为:

In [147]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[147]: 
 A  B
0  0  1
1  2  3
2  4  5
3  6  7

[4 rows x 2 columns] 
```  ### 稀疏变更

这些更改使得 pandas 能够处理更多 dtype 的稀疏数据,并且使数据处理体验更加流畅。

#### 类型`int64`和`bool`支持增强

稀疏数据结构现在获得了对`int64`和`bool` `dtype`的增强支持([GH 667](https://github.com/pandas-dev/pandas/issues/667),[GH 13849](https://github.com/pandas-dev/pandas/issues/13849))。

以前,稀疏数据默认为`float64` dtype,即使所有输入都是`int`或`bool` dtype。您必须明确指定`dtype`才能创建具有`int64` dtype 的稀疏数据。此外,必须显式指定`fill_value`,因为默认值为`np.nan`,而`np.nan`不会出现在`int64`或`bool`数据中。

```py
In [1]: pd.SparseArray([1, 2, 0, 0])
Out[1]:
[1.0, 2.0, 0.0, 0.0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

# specifying int64 dtype, but all values are stored in sp_values because
# fill_value default is np.nan
In [2]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[2]:
[1, 2, 0, 0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

In [3]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64, fill_value=0)
Out[3]:
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32) 

自 v0.19.0 起,稀疏数据保留输入的 dtype,并使用更合适的fill_value默认值(int64 dtype 为0,bool dtype 为False)。

In [148]: pd.arrays.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[148]: 
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32)

In [149]: pd.arrays.SparseArray([True, False, False, False])
Out[149]: 
[True, False, False, False]
Fill: False
IntIndex
Indices: array([0], dtype=int32) 

有关更多详细信息,请参见文档。

运算符现在会保留 dtype

  • 稀疏数据结构现在在算术操作后可以保留dtype(GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype

s + 1 
  • 稀疏数据结构现在支持astype以转换内部的dtype(GH 13900)
s = pd.SparseSeries([1.0, 0.0, 2.0, 0.0], fill_value=0)
s
s.astype(np.int64) 

如果数据包含不能转换为指定dtype的值,则astype会失败。请注意,此限制适用于默认为np.nan的fill_value。

In [7]: pd.SparseSeries([1., np.nan, 2., np.nan], fill_value=np.nan).astype(np.int64)
Out[7]:
ValueError: unable to coerce current fill_value nan to int64 dtype 

其他稀疏修复

  • 当切片或转置时,子类化的SparseDataFrame和SparseSeries现在会保留类类型。 (GH 13787)

  • SparseArray中的bool dtype 现在支持逻辑(bool)运算符(GH 14000)

  • 在使用MultiIndex []索引的SparseSeries中可能会引发IndexError错误(GH 13144)

  • 在使用MultiIndex []索引的SparseSeries中可能出现普通Index的错误结果(GH 13144)

  • SparseDataFrame中的错误,其中axis=None未默认为axis=0(GH 13048)

  • 在包含object dtype 的SparseSeries和SparseDataFrame中创建时可能会引发TypeError的错误(GH 11633)

  • SparseDataFrame 中的 Bug 不遵循传递的 SparseArray 或 SparseSeries 的 dtype 和 fill_value (GH 13866)

  • SparseArray 和 SparseSeries 中的 Bug 不对 fill_value 应用 ufunc (GH 13853)

  • SparseSeries.abs 中的 Bug 不正确地保留了负的 fill_value (GH 13853)

  • 在多类型 SparseDataFrame 上进行单行切片的 Bug,以前强制类型为浮点数 (GH 13917)

  • SparseSeries 切片中的 Bug 会将整数 dtype 更改为浮点数 (GH 8292)

  • SparseDataFarme 中的比较操作 Bug 可能会引发 TypeError (GH 13001)

  • SparseDataFarme.isnull 中的 Bug 会引发 ValueError (GH 8276)

  • 使用 bool dtype 的 SparseSeries 表示中的 Bug 可能会引发 IndexError (GH 13110)

  • SparseSeries 和 SparseDataFrame 中 bool 或 int64 dtype 的 Bug 可能会显示其值,如同 float64 dtype 一样 (GH 13110)

  • 使用 SparseArray 和 bool dtype 进行稀疏索引的 Bug 可能返回不正确的结果 (GH 13985)

  • 从 SparseSeries 创建的 SparseArray 中的 Bug 可能会丢失 dtype (GH 13999)

  • SparseSeries 与密集返回正常 Series 而不是 SparseSeries 的比较中的 Bug (GH 13999) ### 索引器 dtype 变更

注意

此更改仅影响在 Windows 上运行的 64 位 Python,且仅影响相对高级的索引操作。

诸如 Index.get_indexer 这样返回索引器数组的方法,会强制将该数组转换为“平台整数”,以便可以直接在第三方库操作中使用,如 numpy.take。以前,平台整数被定义为 np.int_,对应于 C 整数,但正确的类型,以及现在使用的类型,是 np.intp,对应于可以容纳指针的 C 整数大小 (GH 3033, GH 13972).

在许多平台上,这些类型是相同的,但对于在 Windows 上运行的 64 位 Python,np.int_ 是 32 位,而 np.intp 是 64 位。更改此行为会提高该平台上许多操作的性能。

先前行为:

In [1]: i = pd.Index(['a', 'b', 'c'])

In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int32') 

新行为:

In [1]: i = pd.Index(['a', 'b', 'c'])

In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int64') 
```  ### 其他 API 变更

+   当 `warn=True` 时,`Timestamp.to_pydatetime` 将发出 `UserWarning`,且实例具有非零纳秒数,以前会向 stdout 打印一条消息 ([GH 14101](https://github.com/pandas-dev/pandas/issues/14101)).

+   具有日期时间和时区的`Series.unique()`现在返回带时区的`Timestamp`数组 ([GH 13565](https://github.com/pandas-dev/pandas/issues/13565)).

+   当调用`Panel.to_sparse()`时将会抛出`NotImplementedError`异常 ([GH 13778](https://github.com/pandas-dev/pandas/issues/13778)).

+   当调用`Index.reshape()`时将会抛出`NotImplementedError`异常 ([GH 12882](https://github.com/pandas-dev/pandas/issues/12882)).

+   `.filter()`强制互斥的关键字参数 ([GH 12399](https://github.com/pandas-dev/pandas/issues/12399)).

+   `eval`的`float32`类型的 upcasting 规则已更新为与 NumPy 的规则更一致。 如果您将 pandas 的`float32`对象乘以标量 float64,新行为将不会向上转换为`float64` ([GH 12388](https://github.com/pandas-dev/pandas/issues/12388)).

+   如果在 groupby 或 resample 对象上调用 NumPy ufuncs 如`np.mean`,现在会引发`UnsupportedFunctionCall`错误 ([GH 12811](https://github.com/pandas-dev/pandas/issues/12811)).

+   `__setitem__`将不再将可调用的 rhs 应用为函数而不是存储它。 直接调用`where`以获取以前的行为 ([GH 13299](https://github.com/pandas-dev/pandas/issues/13299)).

+   调用`.sample()`将尊重通过`numpy.random.seed(n)`设置的随机种子 ([GH 13161](https://github.com/pandas-dev/pandas/issues/13161))

+   `Styler.apply`现在对您的函数必须返回的输出更严格。 对于`axis=0`或`axis=1`,输出形状必须相同。 对于`axis=None`,输出必须是具有相同列和索引标签的 DataFrame ([GH 13222](https://github.com/pandas-dev/pandas/issues/13222)).

+   调用`Float64Index.astype(int)`现在如果`Float64Index`包含`NaN`值将会抛出`ValueError`异常 ([GH 13149](https://github.com/pandas-dev/pandas/issues/13149))

+   `TimedeltaIndex.astype(int)`和`DatetimeIndex.astype(int)`现在将返回`Int64Index`而不是`np.array` ([GH 13209](https://github.com/pandas-dev/pandas/issues/13209))

+   将多频率的`Period`传递给普通的`Index`现在将返回`object` dtype 的`Index` ([GH 13664](https://github.com/pandas-dev/pandas/issues/13664))

+   使用`Period`的`PeriodIndex.fillna`现在会强制转换为`object` dtype ([GH 13664](https://github.com/pandas-dev/pandas/issues/13664))

+   从`DataFrame.boxplot(by=col)`绘制的分面箱线图现在在`return_type`不为 None 时返回`Series`。 以前这些返回一个`OrderedDict`。 请注意,当`return_type=None`时,默认情况下,这些仍然返回一个 2-D NumPy 数组 ([GH 12216](https://github.com/pandas-dev/pandas/issues/12216), [GH 7096](https://github.com/pandas-dev/pandas/issues/7096)).

+   `pd.read_hdf`现在将在提供除`r`,`r+`和`a`之外的模式时引发`ValueError`而不是`KeyError`。 ([GH 13623](https://github.com/pandas-dev/pandas/issues/13623))

+   当在不存在的文件上调用`pd.read_csv()`、`pd.read_table()`和`pd.read_hdf()`时,Python 3.x 将引发内置的`FileNotFoundError`异常;这在 Python 2.x 中回溯为`IOError`([GH 14086](https://github.com/pandas-dev/pandas/issues/14086))

+   csv 解析器会传递更多信息的异常。异常类型现在将是原始异常类型,而不是`CParserError`([GH 13652](https://github.com/pandas-dev/pandas/issues/13652))。

+   当`sep`编码超过一个字符长时,C 引擎中的`pd.read_csv()`现在会发出`ParserWarning`或引发`ValueError`([GH 14065](https://github.com/pandas-dev/pandas/issues/14065))

+   `DataFrame.values`现在将返回`float64`,具有混合`int64`和`uint64` dtypes 的`DataFrame`,符合`np.find_common_type`([GH 10364](https://github.com/pandas-dev/pandas/issues/10364)、[GH 13917](https://github.com/pandas-dev/pandas/issues/13917))

+   `.groupby.groups`现在将返回一个`Index`对象的字典,而不是`np.ndarray`或`lists`的字典([GH 14293](https://github.com/pandas-dev/pandas/issues/14293))

### `Series.tolist()`现在将返回 Python 类型

`Series.tolist()`现在将以 Python 类型返回输出,模仿 NumPy 的`.tolist()`行为([GH 10904](https://github.com/pandas-dev/pandas/issues/10904))

```py
In [73]: s = pd.Series([1, 2, 3]) 

以前的行为:

In [7]: type(s.tolist()[0])
Out[7]:
 <class 'numpy.int64'> 

新行为:

In [74]: type(s.tolist()[0])
Out[74]: int 

不同索引的Series运算符

以下Series运算符已更改为使所有运算符一致,包括DataFrame(GH 1134、GH 4581、GH 13538)

  • 当index不同时,Series比较运算符现在会引发ValueError。

  • Series逻辑运算符会对齐左右两侧的index。

警告

在 0.18.1 之前,比较具有相同长度的Series,即使.index不同,也会成功(结果忽略.index)。从 0.19.0 开始,这将引发ValueError以更加严格。本节还描述了如何保持先前的行为或对齐不同的索引,使用灵活的比较方法,如.eq。

因此,Series和DataFrame运算符的行为如下:

算术运算符

算术运算符会对齐index(没有变化)。

In [75]: s1 = pd.Series([1, 2, 3], index=list("ABC"))

In [76]: s2 = pd.Series([2, 2, 2], index=list("ABD"))

In [77]: s1 + s2
Out[77]: 
A    3.0
B    4.0
C    NaN
D    NaN
Length: 4, dtype: float64

In [78]: df1 = pd.DataFrame([1, 2, 3], index=list("ABC"))

In [79]: df2 = pd.DataFrame([2, 2, 2], index=list("ABD"))

In [80]: df1 + df2
Out[80]: 
 0
A  3.0
B  4.0
C  NaN
D  NaN

[4 rows x 1 columns] 

比较运算符

当.index不同时,比较运算符会引发ValueError。

以前的行为(Series):

Series比较值时会忽略.index,只要两者长度相同:

In [1]: s1 == s2
Out[1]:
A    False
B     True
C    False
dtype: bool 

新行为(Series):

In [2]: s1 == s2
Out[2]:
ValueError: Can only compare identically-labeled Series objects 

注

要达到与以前版本相同的结果(根据位置比较值而忽略.index),请同时比较.values。

In [81]: s1.values == s2.values
Out[81]: array([False,  True, False]) 

如果您想比较Series并对齐其.index,请参见下面的灵活比较方法部分:

In [82]: s1.eq(s2)
Out[82]: 
A    False
B     True
C    False
D    False
Length: 4, dtype: bool 

当前行为(DataFrame,无变化):

In [3]: df1 == df2
Out[3]:
ValueError: Can only compare identically-labeled DataFrame objects 

逻辑运算符

逻辑运算符会对齐左右两侧的.index。

先前行为(Series),仅保留左侧index:

In [4]: s1 = pd.Series([True, False, True], index=list('ABC'))
In [5]: s2 = pd.Series([True, True, True], index=list('ABD'))
In [6]: s1 & s2
Out[6]:
A     True
B    False
C    False
dtype: bool 

新行为(Series):

In [83]: s1 = pd.Series([True, False, True], index=list("ABC"))

In [84]: s2 = pd.Series([True, True, True], index=list("ABD"))

In [85]: s1 & s2
Out[85]: 
A     True
B    False
C    False
D    False
Length: 4, dtype: bool 

注意

Series的逻辑运算符会用False填充NaN结果。

注意

要实现与先前版本相同的结果(仅基于左侧index比较值),可以使用reindex_like:

In [86]: s1 & s2.reindex_like(s1)
Out[86]: 
A     True
B    False
C    False
Length: 3, dtype: bool 

当前行为(DataFrame,无变化):

In [87]: df1 = pd.DataFrame([True, False, True], index=list("ABC"))

In [88]: df2 = pd.DataFrame([True, True, True], index=list("ABD"))

In [89]: df1 & df2
Out[89]: 
 0
A   True
B  False
C  False
D  False

[4 rows x 1 columns] 

灵活比较方法

Series的灵活比较方法如eq、ne、le、lt、ge和gt现在会对齐两个index。如果要比较具有不同index的两个Series,请使用这些运算符。

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

In [91]: s2 = pd.Series([2, 2, 2], index=["b", "c", "d"])

In [92]: s1.eq(s2)
Out[92]: 
a    False
b     True
c    False
d    False
Length: 4, dtype: bool

In [93]: s1.ge(s2)
Out[93]: 
a    False
b     True
c     True
d    False
Length: 4, dtype: bool 

以前,这与比较运算符的工作方式相同(见上文)。

算术运算符

算术运算符会对齐两个index(无变化)。

In [75]: s1 = pd.Series([1, 2, 3], index=list("ABC"))

In [76]: s2 = pd.Series([2, 2, 2], index=list("ABD"))

In [77]: s1 + s2
Out[77]: 
A    3.0
B    4.0
C    NaN
D    NaN
Length: 4, dtype: float64

In [78]: df1 = pd.DataFrame([1, 2, 3], index=list("ABC"))

In [79]: df2 = pd.DataFrame([2, 2, 2], index=list("ABD"))

In [80]: df1 + df2
Out[80]: 
 0
A  3.0
B  4.0
C  NaN
D  NaN

[4 rows x 1 columns] 

比较运算符

当.index不同时,比较运算符会引发ValueError。

先前行为(Series):

Series比较值时会忽略.index,只要两者长度相同:

In [1]: s1 == s2
Out[1]:
A    False
B     True
C    False
dtype: bool 

新行为(Series):

In [2]: s1 == s2
Out[2]:
ValueError: Can only compare identically-labeled Series objects 

注意

要实现与先前版本相同的结果(基于位置比较值,忽略.index),请比较.values。

In [81]: s1.values == s2.values
Out[81]: array([False,  True, False]) 

如果要比较对齐其.index的Series,请参见下面的灵活比较方法部分:

In [82]: s1.eq(s2)
Out[82]: 
A    False
B     True
C    False
D    False
Length: 4, dtype: bool 

当前行为(DataFrame,无变化):

In [3]: df1 == df2
Out[3]:
ValueError: Can only compare identically-labeled DataFrame objects 

逻辑运算符

逻辑运算符会对齐左右两侧的.index。

先前行为(Series),仅保留左侧index:

In [4]: s1 = pd.Series([True, False, True], index=list('ABC'))
In [5]: s2 = pd.Series([True, True, True], index=list('ABD'))
In [6]: s1 & s2
Out[6]:
A     True
B    False
C    False
dtype: bool 

新行为(Series):

In [83]: s1 = pd.Series([True, False, True], index=list("ABC"))

In [84]: s2 = pd.Series([True, True, True], index=list("ABD"))

In [85]: s1 & s2
Out[85]: 
A     True
B    False
C    False
D    False
Length: 4, dtype: bool 

注意

Series的逻辑运算符会用False填充NaN结果。

注意

要实现与先前版本相同的结果(仅基于左侧index比较值),可以使用reindex_like:

In [86]: s1 & s2.reindex_like(s1)
Out[86]: 
A     True
B    False
C    False
Length: 3, dtype: bool 

当前行为(DataFrame,无变化):

In [87]: df1 = pd.DataFrame([True, False, True], index=list("ABC"))

In [88]: df2 = pd.DataFrame([True, True, True], index=list("ABD"))

In [89]: df1 & df2
Out[89]: 
 0
A   True
B  False
C  False
D  False

[4 rows x 1 columns] 

灵活比较方法

Series的灵活比较方法如eq、ne、le、lt、ge和gt现在会对齐两个index。如果要比较具有不同index的两个Series,请使用这些运算符。

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

In [91]: s2 = pd.Series([2, 2, 2], index=["b", "c", "d"])

In [92]: s1.eq(s2)
Out[92]: 
a    False
b     True
c    False
d    False
Length: 4, dtype: bool

In [93]: s1.ge(s2)
Out[93]: 
a    False
b     True
c     True
d    False
Length: 4, dtype: bool 

以前,这与比较运算符的工作方式相同(见上文)。

赋值时Series类型提升

Series现在会正确提升其 dtype,以便将不兼容值分配给当前 dtype(GH 13234)

In [94]: s = pd.Series() 

先前行为:

In [2]: s["a"] = pd.Timestamp("2016-01-01")

In [3]: s["b"] = 3.0
TypeError: invalid type promotion 

新行为:

In [95]: s["a"] = pd.Timestamp("2016-01-01")

In [96]: s["b"] = 3.0

In [97]: s
Out[97]: 
a    2016-01-01 00:00:00
b                    3.0
Length: 2, dtype: object

In [98]: s.dtype
Out[98]: dtype('O') 

函数.to_datetime()的更改

以前,如果.to_datetime()遇到混合整数/浮点数和字符串,但没有日期时间且errors='coerce',它会将所有内容转换为NaT。

先前行为:

In [2]: pd.to_datetime([1, 'foo'], errors='coerce')
Out[2]: DatetimeIndex(['NaT', 'NaT'], dtype='datetime64[ns]', freq=None) 

当前行为:

现在将整数/浮点数转换为默认单位为ns。

In [99]: pd.to_datetime([1, "foo"], errors="coerce")
Out[99]: DatetimeIndex(['1970-01-01 00:00:00.000000001', 'NaT'], dtype='datetime64[ns]', freq=None) 

与.to_datetime()相关的错误修复:

  • 在传递整数或浮点数时,且没有unit和errors='coerce'时,pd.to_datetime()存在错误(GH 13180)。

  • 在传递无效数据类型(例如布尔值)时,pd.to_datetime()存在错误;现在将尊重errors关键字(GH 13176)

  • pd.to_datetime()中的错误,在int8和int16数据类型上溢出 (GH 13451)

  • 在errors='ignore'时,pd.to_datetime()中的错误会引发AttributeError,并且另一个字符串无效 (GH 12424)

  • 在指定unit时,pd.to_datetime()中的错误未正确转换浮点数,导致截断的日期时间 (GH 13834)

合并更改

合并现在将保留连接键的数据类型 (GH 8596)

In [100]: df1 = pd.DataFrame({"key": [1], "v1": [10]})

In [101]: df1
Out[101]: 
 key  v1
0    1  10

[1 rows x 2 columns]

In [102]: df2 = pd.DataFrame({"key": [1, 2], "v1": [20, 30]})

In [103]: df2
Out[103]: 
 key  v1
0    1  20
1    2  30

[2 rows x 2 columns] 

先前的行为:

In [5]: pd.merge(df1, df2, how='outer')
Out[5]:
 key    v1
0  1.0  10.0
1  1.0  20.0
2  2.0  30.0

In [6]: pd.merge(df1, df2, how='outer').dtypes
Out[6]:
key    float64
v1     float64
dtype: object 

新行为:

我们能够保留连接键

In [104]: pd.merge(df1, df2, how="outer")
Out[104]: 
 key  v1
0    1  10
1    1  20
2    2  30

[3 rows x 2 columns]

In [105]: pd.merge(df1, df2, how="outer").dtypes
Out[105]: 
key    int64
v1     int64
Length: 2, dtype: object 

当然,如果引入了缺失值,那么结果的数据类型将被提升,这与以前的情况相同。

In [106]: pd.merge(df1, df2, how="outer", on="key")
Out[106]: 
 key  v1_x  v1_y
0    1  10.0    20
1    2   NaN    30

[2 rows x 3 columns]

In [107]: pd.merge(df1, df2, how="outer", on="key").dtypes
Out[107]: 
key       int64
v1_x    float64
v1_y      int64
Length: 3, dtype: object 

方法.describe()的更改

.describe()输出中的百分位标识现在会四舍五入到保持它们不同的最小精度 (GH 13104)

In [108]: s = pd.Series([0, 1, 2, 3, 4])

In [109]: df = pd.DataFrame([0, 1, 2, 3, 4]) 

先前的行为:

百分位数最多四舍五入到小数点后一位,如果数据框中的百分位数重复,可能会引发ValueError。

In [3]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[3]:
count     5.000000
mean      2.000000
std       1.581139
min       0.000000
0.0%      0.000400
0.1%      0.002000
0.1%      0.004000
50%       2.000000
99.9%     3.996000
100.0%    3.998000
100.0%    3.999600
max       4.000000
dtype: float64

In [4]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[4]:
...
ValueError: cannot reindex from a duplicate axis 

新行为:

In [110]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[110]: 
count     5.000000
mean      2.000000
std       1.581139
min       0.000000
0.01%     0.000400
0.05%     0.002000
0.1%      0.004000
50%       2.000000
99.9%     3.996000
99.95%    3.998000
99.99%    3.999600
max       4.000000
Length: 12, dtype: float64

In [111]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999])
Out[111]: 
 0
count   5.000000
mean    2.000000
std     1.581139
min     0.000000
0.01%   0.000400
0.05%   0.002000
0.1%    0.004000
50%     2.000000
99.9%   3.996000
99.95%  3.998000
99.99%  3.999600
max     4.000000

[12 rows x 1 columns] 

此外:

  • 传递重复的percentiles现在会引发ValueError。

  • 在具有混合数据类型列索引的 DataFrame 上调用.describe()时出现的错误,之前会引发TypeError (GH 13288)

Period更改

PeriodIndex现在具有period数据类型

PeriodIndex现在具有自己的period数据类型。period数据类型是一种类似于category或时区感知数据类型 (datetime64[ns, tz]) 的 pandas 扩展数据类型 (GH 13941)。由于这个改变,PeriodIndex不再具有整数数据类型:

先前的行为:

In [1]: pi = pd.PeriodIndex(['2016-08-01'], freq='D')

In [2]: pi
Out[2]: PeriodIndex(['2016-08-01'], dtype='int64', freq='D')

In [3]: pd.api.types.is_integer_dtype(pi)
Out[3]: True

In [4]: pi.dtype
Out[4]: dtype('int64') 

新行为:

In [112]: pi = pd.PeriodIndex(["2016-08-01"], freq="D")

In [113]: pi
Out[113]: PeriodIndex(['2016-08-01'], dtype='period[D]')

In [114]: pd.api.types.is_integer_dtype(pi)
Out[114]: False

In [115]: pd.api.types.is_period_dtype(pi)
Out[115]: True

In [116]: pi.dtype
Out[116]: period[D]

In [117]: type(pi.dtype)
Out[117]: pandas.core.dtypes.dtypes.PeriodDtype 

Period('NaT')现在返回pd.NaT

以前,Period具有与pd.NaT不同的Period('NaT')��示。现在Period('NaT')已更改为返回pd.NaT。 (GH 12759, GH 13582)

先前的行为:

In [5]: pd.Period('NaT', freq='D')
Out[5]: Period('NaT', 'D') 

新行为:

这些结果中提供freq选项时会得到pd.NaT。

In [118]: pd.Period("NaT")
Out[118]: NaT

In [119]: pd.Period(None)
Out[119]: NaT 

为了与Period的加法和减法兼容,pd.NaT现在支持与int的加法和减法。之前会引发ValueError。

先前的行为:

In [5]: pd.NaT + 1
...
ValueError: Cannot add integral value to Timestamp without freq. 

新行为:

In [120]: pd.NaT + 1
Out[120]: NaT

In [121]: pd.NaT - 1
Out[121]: NaT 

PeriodIndex.values现在返回Period对象的数组

.values现在返回一个Period对象的数组,而不是整数的数组 (GH 13988).

先前的行为:

In [6]: pi = pd.PeriodIndex(['2011-01', '2011-02'], freq='M')
In [7]: pi.values
Out[7]: array([492, 493]) 

新行为:

In [122]: pi = pd.PeriodIndex(["2011-01", "2011-02"], freq="M")

In [123]: pi.values
Out[123]: array([Period('2011-01', 'M'), Period('2011-02', 'M')], dtype=object) 

PeriodIndex现在具有period数据类型

PeriodIndex 现在具有自己的 period dtype。period dtype 是一个类似于 category 或 时区感知 dtype (datetime64[ns, tz]) 的 pandas 扩展 dtype。由于这个改变,PeriodIndex 不再具有整数 dtype。

先前的行为:

In [1]: pi = pd.PeriodIndex(['2016-08-01'], freq='D')

In [2]: pi
Out[2]: PeriodIndex(['2016-08-01'], dtype='int64', freq='D')

In [3]: pd.api.types.is_integer_dtype(pi)
Out[3]: True

In [4]: pi.dtype
Out[4]: dtype('int64') 

新行为:

In [112]: pi = pd.PeriodIndex(["2016-08-01"], freq="D")

In [113]: pi
Out[113]: PeriodIndex(['2016-08-01'], dtype='period[D]')

In [114]: pd.api.types.is_integer_dtype(pi)
Out[114]: False

In [115]: pd.api.types.is_period_dtype(pi)
Out[115]: True

In [116]: pi.dtype
Out[116]: period[D]

In [117]: type(pi.dtype)
Out[117]: pandas.core.dtypes.dtypes.PeriodDtype 

Period('NaT') 现在返回 pd.NaT

以前,Period 具有自己的 Period('NaT') 表示,不同于 pd.NaT。现在,Period('NaT') 已经更改为返回 pd.NaT。

先前的行为:

In [5]: pd.Period('NaT', freq='D')
Out[5]: Period('NaT', 'D') 

新行为:

这些会在不提供 freq 选项的情况下产生 pd.NaT。

In [118]: pd.Period("NaT")
Out[118]: NaT

In [119]: pd.Period(None)
Out[119]: NaT 

为了与 Period 的加法和减法兼容,pd.NaT 现在支持与 int 的加法和减法。以前会引发 ValueError。

先前的行为:

In [5]: pd.NaT + 1
...
ValueError: Cannot add integral value to Timestamp without freq. 

新行为:

In [120]: pd.NaT + 1
Out[120]: NaT

In [121]: pd.NaT - 1
Out[121]: NaT 

PeriodIndex.values 现在返回 Period 对象的数组。

.values 被更改为返回 Period 对象的数组,而不是整数数组。

先前的行为:

In [6]: pi = pd.PeriodIndex(['2011-01', '2011-02'], freq='M')
In [7]: pi.values
Out[7]: array([492, 493]) 

新行为:

In [122]: pi = pd.PeriodIndex(["2011-01", "2011-02"], freq="M")

In [123]: pi.values
Out[123]: array([Period('2011-01', 'M'), Period('2011-02', 'M')], dtype=object) 

Index + / - 不再用于集合操作

先前的基本 Index 类型和 DatetimeIndex (而不是数值索引类型) 的加法和减法已经执行了集合操作 (集合并和差)。这个行为从 0.15.0 开始已经被弃用 (而使用特定的 .union() 和 .difference() 方法),现在已被禁用。现在尽可能使用 + 和 - 进行逐元素操作,例如连接字符串或减去日期时间。

先前的行为:

In [1]: pd.Index(['a', 'b']) + pd.Index(['a', 'c'])
FutureWarning: using '+' to provide set union with Indexes is deprecated, use '|' or .union()
Out[1]: Index(['a', 'b', 'c'], dtype='object') 

新行为:相同的操作现在将执行逐元素加法:

In [124]: pd.Index(["a", "b"]) + pd.Index(["a", "c"])
Out[124]: Index(['aa', 'bc'], dtype='object') 

注意,数字索引对象已经执行了逐元素操作。例如,添加两个整数索引的行为不变。现在,基本的 Index 已经与此行为保持一致。

In [125]: pd.Index([1, 2, 3]) + pd.Index([2, 3, 4])
Out[125]: Index([3, 5, 7], dtype='int64') 

此外,由于这个改变,现在可以减去两个 DatetimeIndex 对象,得到一个 TimedeltaIndex:

先前的行为:

In [1]: (pd.DatetimeIndex(['2016-01-01', '2016-01-02'])
 ...: - pd.DatetimeIndex(['2016-01-02', '2016-01-03']))
FutureWarning: using '-' to provide set differences with datetimelike Indexes is deprecated, use .difference()
Out[1]: DatetimeIndex(['2016-01-01'], dtype='datetime64[ns]', freq=None) 

新行为:

In [126]: (
 .....:    pd.DatetimeIndex(["2016-01-01", "2016-01-02"])
 .....:    - pd.DatetimeIndex(["2016-01-02", "2016-01-03"])
 .....: )
 .....: 
Out[126]: TimedeltaIndex(['-1 days', '-1 days'], dtype='timedelta64[ns]', freq=None) 

Index.difference 和 .symmetric_difference 的更改

Index.difference 和 Index.symmetric_difference 现在会更一致地将 NaN 值视为任何其他值。

In [127]: idx1 = pd.Index([1, 2, 3, np.nan])

In [128]: idx2 = pd.Index([0, 1, np.nan]) 

先前的行为:

In [3]: idx1.difference(idx2)
Out[3]: Float64Index([nan, 2.0, 3.0], dtype='float64')

In [4]: idx1.symmetric_difference(idx2)
Out[4]: Float64Index([0.0, nan, 2.0, 3.0], dtype='float64') 

新行为:

In [129]: idx1.difference(idx2)
Out[129]: Index([2.0, 3.0], dtype='float64')

In [130]: idx1.symmetric_difference(idx2)
Out[130]: Index([0.0, 2.0, 3.0], dtype='float64') 

Index.unique 一致地返回 Index

Index.unique() 现在将唯一值作为适当 dtype 的 Index 返回。先前,大多数 Index 类返回 np.ndarray,而 DatetimeIndex、TimedeltaIndex 和 PeriodIndex 返回 Index 以保留元数据如时区。

之前的行为:

In [1]: pd.Index([1, 2, 3]).unique()
Out[1]: array([1, 2, 3])

In [2]: pd.DatetimeIndex(['2011-01-01', '2011-01-02',
 ...:                  '2011-01-03'], tz='Asia/Tokyo').unique()
Out[2]:
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
 '2011-01-03 00:00:00+09:00'],
 dtype='datetime64[ns, Asia/Tokyo]', freq=None) 

新行为:

In [131]: pd.Index([1, 2, 3]).unique()
Out[131]: Index([1, 2, 3], dtype='int64')

In [132]: pd.DatetimeIndex(
 .....:    ["2011-01-01", "2011-01-02", "2011-01-03"], tz="Asia/Tokyo"
 .....: ).unique()
 .....: 
Out[132]: 
DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00',
 '2011-01-03 00:00:00+09:00'],
 dtype='datetime64[ns, Asia/Tokyo]', freq=None) 

MultiIndex 构造函数、groupby 和 set_index 保留分类 dtype

MultiIndex.from_arrays 和 MultiIndex.from_product 现在将在MultiIndex级别中保留分类 dtype(GH 13743,GH 13854)。

In [133]: cat = pd.Categorical(["a", "b"], categories=list("bac"))

In [134]: lvl1 = ["foo", "bar"]

In [135]: midx = pd.MultiIndex.from_arrays([cat, lvl1])

In [136]: midx
Out[136]: 
MultiIndex([('a', 'foo'),
 ('b', 'bar')],
 ) 

之前的行为:

In [4]: midx.levels[0]
Out[4]: Index(['b', 'a', 'c'], dtype='object')

In [5]: midx.get_level_values[0]
Out[5]: Index(['a', 'b'], dtype='object') 

新行为:单个级别现在是一个CategoricalIndex:

In [137]: midx.levels[0]
Out[137]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category')

In [138]: midx.get_level_values(0)
Out[138]: CategoricalIndex(['a', 'b'], categories=['b', 'a', 'c'], ordered=False, dtype='category') 

MultiIndex.from_product也进行了类似的更改。因此,groupby 和 set_index 也在索引中保留了分类 dtypes

In [139]: df = pd.DataFrame({"A": [0, 1], "B": [10, 11], "C": cat})

In [140]: df_grouped = df.groupby(by=["A", "C"], observed=False).first()

In [141]: df_set_idx = df.set_index(["A", "C"]) 

之前的行为:

In [11]: df_grouped.index.levels[1]
Out[11]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [12]: df_grouped.reset_index().dtypes
Out[12]:
A      int64
C     object
B    float64
dtype: object

In [13]: df_set_idx.index.levels[1]
Out[13]: Index(['b', 'a', 'c'], dtype='object', name='C')
In [14]: df_set_idx.reset_index().dtypes
Out[14]:
A      int64
C     object
B      int64
dtype: object 

新行为:

In [142]: df_grouped.index.levels[1]
Out[142]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')

In [143]: df_grouped.reset_index().dtypes
Out[143]: 
A       int64
C    category
B     float64
Length: 3, dtype: object

In [144]: df_set_idx.index.levels[1]
Out[144]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C')

In [145]: df_set_idx.reset_index().dtypes
Out[145]: 
A       int64
C    category
B       int64
Length: 3, dtype: object 

函数read_csv将逐步枚举块

当使用chunksize=n调用read_csv()并且没有指定索引时,每个块过去都有一个独立生成的索引,从0到n-1。现在,它们被赋予一个逐渐增加的索引,从第一个块的0开始,从第二个块的n开始,依此类推,以便在连接时与没有chunksize=参数调用read_csv()的结果相同(GH 12185)。

In [146]: data = "A,B\n0,1\n2,3\n4,5\n6,7" 

之前的行为:

In [2]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[2]:
 A  B
0  0  1
1  2  3
0  4  5
1  6  7 

新行为:

In [147]: pd.concat(pd.read_csv(StringIO(data), chunksize=2))
Out[147]: 
 A  B
0  0  1
1  2  3
2  4  5
3  6  7

[4 rows x 2 columns] 

稀疏变更

这些变化允许 pandas 处理更多 dtypes 的稀疏数据,并使数据处理体验更加顺畅。

类型int64和bool支持增强

稀疏数据结构现在增强支持int64和bool dtype(GH 667,GH 13849)。

以前,稀疏数据默认情况下为float64 dtype,即使所有输入都是int或bool dtype。您必须显式指定dtype才能创建具有int64 dtype的稀疏数据。此外,必须显式指定fill_value,因为默认值为np.nan,而np.nan不会出现在int64或bool数据中。

In [1]: pd.SparseArray([1, 2, 0, 0])
Out[1]:
[1.0, 2.0, 0.0, 0.0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

# specifying int64 dtype, but all values are stored in sp_values because
# fill_value default is np.nan
In [2]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[2]:
[1, 2, 0, 0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

In [3]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64, fill_value=0)
Out[3]:
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32) 

从 v0.19.0 开始,稀疏数据保留输入 dtype,并使用更合适的fill_value默认值(int64 dtype 为0,bool dtype 为False)。

In [148]: pd.arrays.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[148]: 
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32)

In [149]: pd.arrays.SparseArray([True, False, False, False])
Out[149]: 
[True, False, False, False]
Fill: False
IntIndex
Indices: array([0], dtype=int32) 

请参阅文档以了解更多详情。

操作符现在保留 dtypes

  • 稀疏数据结构现在可以在算术运算后保留dtype(GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype

s + 1 
  • 稀疏数据结构现在支持astype将内部的dtype转换为指定类型(GH 13900)
s = pd.SparseSeries([1.0, 0.0, 2.0, 0.0], fill_value=0)
s
s.astype(np.int64) 

如果数据包含无法转换为指定dtype的值,则astype会失败。请注意,这个限制适用于默认为np.nan的fill_value。

In [7]: pd.SparseSeries([1., np.nan, 2., np.nan], fill_value=np.nan).astype(np.int64)
Out[7]:
ValueError: unable to coerce current fill_value nan to int64 dtype 

其他稀疏修复

  • 继承的SparseDataFrame和SparseSeries现在在切片或转置时保留类类型。 (GH 13787)

  • SparseArray与bool dtype 现在支持逻辑(bool)运算符(GH 14000)

  • 使用MultiIndex [] 索引的SparseSeries的错误可能会引发IndexError(GH 13144)

  • 具有MultiIndex [] 索引的SparseSeries的错误可能具有普通的Index结果(GH 13144)

  • 在SparseDataFrame中的错误,其中axis=None没有默认为axis=0(GH 13048)

  • 使用object dtype 创建SparseSeries和SparseDataFrame的错误可能会引发TypeError(GH 11633)

  • 在SparseDataFrame中的错误不尊重传递的SparseArray或SparseSeries的 dtype 和fill_value(GH 13866)

  • 在SparseArray和SparseSeries中不应用 ufunc 到fill_value的错误(GH 13853)

  • SparseSeries.abs中的错误不正确地保留了负的fill_value(GH 13853)

  • 在多类型SparseDataFrame上的单行切片中的错误,之前类型被强制为浮点数(GH 13917)

  • 在SparseSeries切片中的错误将整数 dtype 更改为浮点数(GH 8292)

  • 在SparseDataFarme比较操作中的错误可能会引发TypeError(GH 13001)

  • 在SparseDataFarme.isnull中的错误引发了ValueError(GH 8276)

  • 在SparseSeries表示中带有bool dtype 的错误可能会引发IndexError(GH 13110)

  • 具有bool或int64 dtype 的SparseSeries和SparseDataFrame的错误可能显示其值像float64 dtype 一样(GH 13110)

  • 使用bool dtype 的SparseArray进行稀疏索引可能返回不正确的结果(GH 13985)

  • 从SparseSeries创建的SparseArray中的错误可能会丢失dtype(GH 13999)

  • 与密集比较的SparseSeries的错误返回普通的Series而不是SparseSeries(GH 13999)

类型int64和bool的支持增强

稀疏数据结构现在增强了对int64和bool dtype的支持(GH 667, GH 13849)。

以前,即使所有输入都是 int 或 bool dtype,稀疏数据默认为 float64 dtype。您必须显式指定 dtype 来创建具有 int64 dtype 的稀疏数据。此外,fill_value 必须显式指定,因为默认值为 np.nan,而 np.nan 不会出现在 int64 或 bool 数据中。

In [1]: pd.SparseArray([1, 2, 0, 0])
Out[1]:
[1.0, 2.0, 0.0, 0.0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

# specifying int64 dtype, but all values are stored in sp_values because
# fill_value default is np.nan
In [2]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[2]:
[1, 2, 0, 0]
Fill: nan
IntIndex
Indices: array([0, 1, 2, 3], dtype=int32)

In [3]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64, fill_value=0)
Out[3]:
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32) 

从 v0.19.0 开始,稀疏数据保留输入的 dtype,并使用更合适的 fill_value 默认值(int64 dtype 为 0,bool dtype 为 False)。

In [148]: pd.arrays.SparseArray([1, 2, 0, 0], dtype=np.int64)
Out[148]: 
[1, 2, 0, 0]
Fill: 0
IntIndex
Indices: array([0, 1], dtype=int32)

In [149]: pd.arrays.SparseArray([True, False, False, False])
Out[149]: 
[True, False, False, False]
Fill: False
IntIndex
Indices: array([0], dtype=int32) 

更多详情请参见文档。

现在运算符会保留 dtype

  • 稀疏数据结构现在可以在算术操作后保留 dtype(GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64)
s.dtype

s + 1 
  • 稀疏数据结构现在支持 astype 来转换内部的 dtype(GH 13900)
s = pd.SparseSeries([1.0, 0.0, 2.0, 0.0], fill_value=0)
s
s.astype(np.int64) 

如果数据包含不能转换为指定 dtype 的值,则 astype 失败。请注意,此限制适用于默认值为 np.nan 的 fill_value。

In [7]: pd.SparseSeries([1., np.nan, 2., np.nan], fill_value=np.nan).astype(np.int64)
Out[7]:
ValueError: unable to coerce current fill_value nan to int64 dtype 

其他稀疏修复

  • 当切片或转置时,子类化的 SparseDataFrame 和 SparseSeries 现在会保留类类型。 (GH 13787)

  • bool 类型的 SparseArray 现在支持逻辑(bool)运算(GH 14000)

  • MultiIndex 中 SparseSeries 的 Bug 使用 [] 索引可能引发 IndexError(GH 13144)

  • MultiIndex 中 SparseSeries 的 Bug 使用 [] 索引结果可能有普通的 Index(GH 13144)

  • SparseDataFrame 中的 Bug,其中 axis=None 不会默认为 axis=0(GH 13048)

  • 使用 object dtype 创建 SparseSeries 和 SparseDataFrame 的 Bug 可能会引发 TypeError(GH 11633)

  • SparseDataFrame 中的 Bug 不遵循传递的 SparseArray 或 SparseSeries 的 dtype 和 fill_value(GH 13866)

  • SparseArray 和 SparseSeries 中的 Bug 不会将 ufunc 应用到 fill_value(GH 13853)

  • SparseSeries.abs 中的 Bug 错误地保留了负的 fill_value(GH 13853)

  • 单行切片在多类型的 SparseDataFrame 上的 Bug,以前会被强制转换为 float 类型(GH 13917)

  • SparseSeries 切片中的 Bug 会将整数 dtype 更改为 float 类型(GH 8292)

  • SparseDataFarme 中的比较操作可能会引发 TypeError 的 Bug(GH 13001)

  • SparseDataFarme.isnull 中的 Bug 引发 ValueError(GH 8276)

  • 使用bool dtype 的SparseSeries表示中的错误可能会引发IndexError(GH 13110)。

  • 使用bool或int64 dtype 的SparseSeries和SparseDataFrame中的错误可能会显示其值,例如float64 dtype(GH 13110).

  • 使用bool dtype 的SparseArray进行稀疏索引的错误可能会返回不正确的结果(GH 13985)。

  • 从SparseSeries创建的SparseArray中的错误可能会丢失dtype(GH 13999)。

  • 与密集返回普通Series而不是SparseSeries的SparseSeries比较中的错误已修复(GH 13999)。

索引器 dtype 更改

注意

此更改仅影响在 Windows 上运行的 64 位 Python,并且仅影响相对较高级的索引操作。

返回索引器数组的方法(例如Index.get_indexer)会将该数组强制转换为“平台整数”,以便可以直接在第三方库操作(如numpy.take)中使用。以前,平台整数被定义为np.int_,它对应于 C 整数,但正确的类型,以及现在正在使用的类型是np.intp,它对应于可以容纳指针的 C 整数大小(GH 3033,GH 13972)。

这些类型在许多平台上相同,但对于 Windows 上的 64 位 Python,np.int_是 32 位,np.intp是 64 位。更改此行为可以改善该平台上许多操作的性能。

先前的行为:

In [1]: i = pd.Index(['a', 'b', 'c'])

In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int32') 

新行为:

In [1]: i = pd.Index(['a', 'b', 'c'])

In [2]: i.get_indexer(['b', 'b', 'c']).dtype
Out[2]: dtype('int64') 

其他 API 更改

  • 当warn=True且实例具有非零纳秒数时,Timestamp.to_pydatetime将发出UserWarning,之前这会将消息打印到 stdout(GH 14101)。

  • 带有日期时间和时区的Series.unique()现在返回带有时区的Timestamp数组(GH 13565)。

  • 当调用时,Panel.to_sparse()会引发NotImplementedError异常(GH 13778)。

  • 当调用时,Index.reshape()会引发NotImplementedError异常(GH 12882)。

  • .filter()强制执行关键字参数的互斥(GH 12399)。

  • eval的float32类型的提升规则已更新为与 NumPy 的规则更一致。如果您将 pandas 的float32对象与标量 float64 相乘,则新行为不会提升为float64(GH 12388)。

  • 现在,如果在分组或重采样对象上调用 NumPy 的 ufuncs(如np.mean)会引发UnsupportedFunctionCall错误(GH 12811)。

  • __setitem__ 现在不再将可调用的 rhs 视为函数而不是存储它。直接调用 where 来获取先前的行为 (GH 13299).

  • 对 .sample() 的调用将尊重通过 numpy.random.seed(n) 设置的随机种子 (GH 13161)

  • Styler.apply 现在对您的函数必须返回的输出更加严格。对于 axis=0 或 axis=1,输出形状必须相同。对于 axis=None,输出必须是具有相同列和索引标签的 DataFrame (GH 13222).

  • 如果 Float64Index 包含 NaN 值,Float64Index.astype(int) 现在会引发 ValueError (GH 13149)

  • TimedeltaIndex.astype(int) 和 DatetimeIndex.astype(int) 现在将返回 Int64Index 而不是 np.array (GH 13209)

  • 将具有多个频率的 Period 传递给普通的 Index 现在将返回具有 object dtype 的 Index (GH 13664)

  • 使用 Period 的 PeriodIndex.fillna 现在强制转换为 object dtype (GH 13664)

  • 从 DataFrame.boxplot(by=col) 获得的分面箱线图现在在 return_type 不为 None 时返回 Series。以前这些返回一个 OrderedDict。请注意,当 return_type=None 时,默认情况下,这些仍然返回一个 2-D NumPy 数组 (GH 12216,GH 7096).

  • 如果 pd.read_hdf 提供的模式不是 r、r+ 和 a 中的一个,现在会引发 ValueError 而不是 KeyError。(GH 13623)

  • 当在不存在的文件上调用 pd.read_csv()、pd.read_table() 和 pd.read_hdf() 时,Python 3.x 中将引发内置的 FileNotFoundError 异常;在 Python 2.x 中将其作为 IOError 进行回退 (GH 14086)

  • csv 解析器传递更具信息性的异常。异常类型现在将是原始异常类型,而不是 CParserError (GH 13652).

  • 在 C 引擎中使用 pd.read_csv() 当 sep 编码超过一个字符长时将会发出 ParserWarning 或引发 ValueError (GH 14065)

  • DataFrame.values 现在会返回 float64 类型的混合 int64 和 uint64 dtypes 的 DataFrame,符合 np.find_common_type 规范(GH 10364,GH 13917)

  • .groupby.groups 现在将返回 Index 对象的字典,而不是 np.ndarray 或 lists 的字典 (GH 14293)

弃用

  • Series.reshape 和 Categorical.reshape 已被弃用,并将在后续版本中移除(GH 12882, GH 12882)

  • PeriodIndex.to_datetime 已被弃用,推荐使用 PeriodIndex.to_timestamp(GH 8254)

  • Timestamp.to_datetime 已被弃用,推荐使用 Timestamp.to_pydatetime(GH 8254)

  • Index.to_datetime 和 DatetimeIndex.to_datetime 已被弃用,推荐使用 pd.to_datetime(GH 8254)

  • pandas.core.datetools 模块已被弃用,并将在后续版本中移除(GH 14094)

  • SparseList 已被弃用,并将在将来的版本中移除(GH 13784)

  • DataFrame.to_html() 和 DataFrame.to_latex() 已删除 colSpace 参数,推荐使用 col_space(GH 13857)

  • DataFrame.to_sql() 已弃用 flavor 参数,因为在未安装 SQLAlchemy 时它是多余的(GH 13611)

  • 弃用的 read_csv 关键字:

    • compact_ints 和 use_unsigned 已被弃用,并将在将来的版本中移除(GH 13320)

    • buffer_lines 已被弃用,并将在将来的版本中移除(GH 13360)

    • as_recarray 已被弃用,并将在将来的版本中移除(GH 13373)

    • skip_footer 已被弃用,推荐使用 skipfooter,并将在将来的版本中移除(GH 13349)

  • 顶层 pd.ordered_merge() 已重命名为 pd.merge_ordered(),原始名称将在将来的版本中移除(GH 13358)

  • Timestamp.offset 属性(以及构造函数中的命名参数)已被弃用,推荐使用 freq(GH 12160)

  • pd.tseries.util.pivot_annual 已被弃用。使用 pivot_table 作为替代,一个示例在这里(GH 736)

  • pd.tseries.util.isleapyear 已被弃用,并将在后续版本中移除。Datetime-likes 现在具有 .is_leap_year 属性(GH 13727)

  • Panel4D和PanelND构造函数已被弃用,并将在将来的版本中移除。推荐表示这些类型的 n 维数据的方法是使用xarray package。pandas 提供了一个to_xarray()方法来自动执行此转换(GH 13564)

  • pandas.tseries.frequencies.get_standard_freq已被弃用。请使用pandas.tseries.frequencies.to_offset(freq).rule_code代替(GH 13874)

  • pandas.tseries.frequencies.to_offset的freqstr关键字已被弃用,转而使用freq(GH 13874)

  • Categorical.from_array已被弃用,并将在将来的版本中移除(GH 13854)

移除之前版本的弃用/更改

  • SparsePanel类已被移除(GH 13778)

  • pd.sandbox模块已被移除,转而使用外部库pandas-qt(GH 13670)

  • pandas.io.data和pandas.io.wb模块已被移除,转而使用pandas-datareader package(GH 13724)

  • pandas.tools.rplot模块已被移除,转而使用seaborn package(GH 13855)

  • DataFrame.to_csv()已经放弃了engine参数,因为在 0.17.1 中已经弃用(GH 11274,GH 13419)

  • DataFrame.to_dict()已经放弃了outtype参数,转而使用orient(GH 13627,GH 8486)

  • pd.Categorical已经放弃了直接设置ordered属性,转而使用set_ordered方法(GH 13671)

  • pd.Categorical已经放弃了levels属性,转而使用categories(GH 8376)

  • DataFrame.to_sql()已经放弃了mysql选项,用于flavor参数(GH 13611)

  • Panel.shift()已经放弃了lags参数,转而使用periods(GH 14041)

  • pd.Index已经放弃了diff方法,转而使用difference(GH 13669)

  • pd.DataFrame已经放弃了to_wide方法,转而使用to_panel(GH 14039)

  • Series.to_csv已经放弃了nanRep参数,转而使用na_rep(GH 13804)

  • Series.xs、DataFrame.xs、Panel.xs、Panel.major_xs 和 Panel.minor_xs 已经移除了 copy 参数(GH 13781)。

  • str.split 已经放弃了 return_type 参数,改为使用 expand 参数(GH 13701)。

  • 移除了自 0.17.0 起已弃用的旧时间规则(偏移别名)(自 0.8.0 起已是别名)(GH 13590,GH 13868)。现在,旧的时间规则会引发 ValueError。当前支持的偏移列表请参见这里。

  • DataFrame.plot.box 和 DataFrame.boxplot 的 return_type 参数的默认值从 None 改为了 "axes"。这些方法现在默认返回一个 matplotlib axes,而不是一个艺术家字典。请参阅这里(GH 6581)。

  • pandas.io.sql 模块中的 tquery 和 uquery 函数已移除(GH 5950)。

性能改进

  • 改进了稀疏 IntIndex.intersect 的性能(GH 13082)。

  • 当块数较大时,通过稀疏算术与 BlockIndex 的性能得到了改进,尽管在这种情况下建议使用 IntIndex(GH 13082)。

  • DataFrame.quantile() 的性能得到了改进,现在它是基于块操作的(GH 11623)。

  • 通过改进 float64 哈希表操作的性能,修复了一些 Python 3 中非常慢的索引和 groupby 操作(GH 13166,GH 13334)。

  • 改进了 DataFrameGroupBy.transform 的性能(GH 12737)。

  • 改进了 Index 和 Series 的 .duplicated 的性能(GH 10235)。

  • 改进了 Index.difference 的性能(GH 12044)。

  • 改进了 RangeIndex.is_monotonic_increasing 和 is_monotonic_decreasing 的性能(GH 13749)。

  • 改进了 DatetimeIndex 中日期时间字符串解析的性能(GH 13692)。

  • 改进了 Period 的哈希性能(GH 12817)。

  • 改进了带有时区的日期时间的 factorize 的性能(GH 13750)。

  • 通过在更大的索引上延迟创建索引哈希表,改进了索引性能(GH 14266)。

  • 改进了groupby.groups的性能。(GH 14293)

  • 当检查内存使用情况时,不必要地实现一个 MultiIndex。(GH 14308)

修复的 bug

  • 在groupby().shift()中存在的一个 bug,在按列分组时,当存在缺失值时,在极少情况下可能导致段错误或数据损坏。(GH 13813)

  • 在groupby().cumsum()中存在的一个 bug,在axis=1时计算cumprod。(GH 13994)

  • 在pd.to_timedelta()中存在的一个 bug,未能尊重errors参数。(GH 13613)

  • 在io.json.json_normalize()中存在的一个 bug,非 ASCII 键会引发异常。(GH 13213)

  • 在.plot()中将非默认索引的Series作为xerr或yerr传递时存在的一个 bug。(GH 11858)

  • 在区域图绘制中存在的一个 bug,如果启用了子图或在绘图后移动图例,图例会被错误地绘制(需要 matplotlib 1.5.0 才能正确绘制区域图图例)。(GH 9161, GH 13544)

  • 在使用对象数据类型Index进行DataFrame赋值时存在的一个 bug,导致结果列对原始对象可变。(GH 13522)

  • 在 matplotlib AutoDataFormatter中存在的一个 bug;这将恢复第二个缩放格式并重新添加微秒缩放格式。(GH 13131)

  • 在使用固定格式和指定start和/或stop的HDFStore进行选择时,现在将返回所选范围。(GH 8287)

  • 在Categorical.from_codes()中存在的一个 bug,当传递无效的ordered参数时会引发一个无用的错误。(GH 14058)

  • 在 Windows 上从整数元组构建Series时未返回默认的数据类型(int64)的 bug。(GH 13646)

  • 在TimedeltaIndex与类似日期时间对象相加时存在的一个 bug,未能捕获加法溢出。(GH 14068)

  • 在多次调用相同对象时,.groupby(..).resample(..)中存在的一个 bug。(GH 13174)

  • 在索引名称为 Unicode 字符串时,.to_records()中存在的一个 bug。(GH 13172)

  • 在调用未实现的对象上的.memory_usage()中存在的一个 bug。(GH 12924)

  • 具有 nans 的Series.quantile中的回归(也出现在.median()和.describe()中);此外,现在使用分位数命名Series(GH 13098,GH 13146)

  • 具有日期时间值和缺失组的SeriesGroupBy.transform中的错误(GH 13191)

  • 空Series在类似日期时间的数值操作中被错误地强制转换的错误(GH 13844)

  • 当传递带有时区的日期时间的Categorical时,Categorical构造函数中的错误(GH 14190)

  • 使用str索引时,Series.str.extractall()引发ValueError的错误(GH 13156)

  • 使用单个组和量词时,Series.str.extractall()中的错误(GH 13382)

  • DatetimeIndex和Period相减引发ValueError或AttributeError而不是TypeError的错误(GH 13078)

  • 使用NaN和NaT混合数据创建的Index和Series可能没有datetime64数据类型的错误(GH 13324)

  • 可能会忽略np.datetime64('nat')和np.timdelta64('nat')以推断数据类型的错误(GH 13324)

  • PeriodIndex和Period相减引发AttributeError的错误(GH 13071)

  • 在某些情况下返回float64索引的PeriodIndex构造中的错误(GH 13067)

  • 使用空时,.resample(..)中的PeriodIndex不会适当地更改其freq的错误(GH 13067)

  • 使用空DataFrame时,.resample(..)中的PeriodIndex不会保留其类型或名称的错误(GH 13212)

  • 当传递的函数每组返回标量值时,groupby(..).apply(..)中的错误(GH 13468)

  • 传递某些关键字会引发异常的groupby(..).resample(..)中的错误(GH 13235)

  • 依赖于索引排序以获得正确结果的 tz-awareDateTimeIndex上的.tz_convert中的错误(GH 13306)

  • 使用dateutil.tz.tzlocal的.tz_localize可能返回不正确的结果的错误(GH 13583)

  • 使用dateutil.tz.tzlocal的DatetimeTZDtype数据类型无法被视为有效数据类型的错误(GH 13583)

  • Bug in pd.read_hdf() 在尝试加载具有单个数据集且具有一个或多个分类列的 HDF 文件时失败,除非将 key 参数设置为数据集的名称。(GH 13231)

  • Bug in .rolling() 允许在构建 Rolling() 对象时使用负整数窗口,但在聚合时会失败。(GH 13383)

  • Bug in 使用元组值数据和数值索引的 Series 索引。(GH 13509)

  • Bug in 打印 pd.DataFrame 时,具有 object dtype 的异常元素导致段错误。(GH 13717)

  • Bug in 排名 Series 可能导致段错误。(GH 13445)

  • Bug in 各种索引类型,未传播传递的索引名称。(GH 12309)

  • Bug in DatetimeIndex,未遵守 copy=True。(GH 13205)

  • Bug in DatetimeIndex.is_normalized 对于本地时区的规范化 date_range 返回不正确。(GH 13459)

  • Bug in pd.concat 和 .append 可能会将 datetime64 和 timedelta 强制转换为包含 Python 内置 datetime 或 timedelta 而不是 Timestamp 或 Timedelta 的 object dtype。(GH 13626)

  • Bug in PeriodIndex.append 当结果为 object dtype 时可能引发 AttributeError。(GH 13221)

  • Bug in CategoricalIndex.append 可能接受普通的 list。(GH 13626)

  • Bug in pd.concat 和 .append 具有相同时区时,会重置为 UTC。(GH 7795)

  • Bug in Series 和 DataFrame .append 如果���据包含接近 DST 边界的日期时间,则引发 AmbiguousTimeError。(GH 13626)

  • Bug in DataFrame.to_csv() 中,即使仅为非数字值指定引号,浮点值也被引用。(GH 12922, GH 13259)

  • Bug in DataFrame.describe() 仅包含布尔列时引发 ValueError。(GH 13898)

  • Bug in MultiIndex 切片中,当级别非唯一时,会返回额外的元素。(GH 12896)

  • Bug in .str.replace 对于无效的替换不会引发 TypeError。(GH 13438)

  • Bug in MultiIndex.from_arrays 未检查输入数组长度是否匹配。(GH 13599)

  • 在 cartesian_product 和 MultiIndex.from_product 中存在一个 bug,可能会因为空输入数组而引发错误(GH 12258)。

  • 在极少情况下,使用大块数据流/文件进行迭代时,pd.read_csv() 中存在一个 bug,可能导致 segfault 或数据损坏(GH 13703)。

  • 在 pd.read_csv() 中存在一个 bug,当传递包含标量的字典作为 na_values 参数时,会引发错误(GH 12224)。

  • 在 pd.read_csv() 中存在一个 bug,由于未忽略 BOM(字节顺序标记),导致 BOM 文件被错误解析(GH 4793)。

  • 在 pd.read_csv() 中存在一个 bug,当传递一个 numpy 数组作为 usecols 参数时,会引发错误(GH 12546)。

  • 当使用 thousands 参数解析日期时,pd.read_csv() 中的索引列被错误解析为日期(GH 14066)。

  • 在 pd.read_csv() 中存在一个 bug,当数据被转换为数值后,未能正确检测到 NaN 值(GH 13314)。

  • 在两种引擎中,pd.read_csv() 中的 nrows 参数未被正确验证(GH 10476)。

  • 在 pd.read_csv() 中存在一个 bug,未能正确解释大小写混合形式的无穷大数值(GH 13274)。

  • 在 pd.read_csv() 中存在一个 bug,当 engine='python' 时,尾随的 NaN 值未被解析(GH 13320)。

  • 在 Windows 中使用 Python 3 时,从 tempfile.TemporaryFile 读取时,pd.read_csv() 中存在一个 bug(GH 13398)。

  • 在 pd.read_csv() 中存在一个 bug,阻止 usecols 参数接受单字节 Unicode 字符串(GH 13219)。

  • 在 pd.read_csv() 中存在一个 bug,阻止 usecols 参数为空集合(GH 13402)。

  • 在 C 引擎中,pd.read_csv() 存在一个 bug,未能将 NULL 字符解析为 NULL(GH 14012)。

  • 在 pd.read_csv() 中存在一个 bug,当 quoting 被指定为 None 时,不接受 NULL 的 quotechar,即使 quoting 参数被指定为 None(GH 13411)。

  • 在 pd.read_csv() 中存在一个 bug,当引号被指定为非数值时,字段未正确转换为浮点数(GH 13411)。

  • 在 Python 2.x 中,pd.read_csv() 存在一个 bug,处理非 UTF8 编码的、多字符分隔的数据时会出现问题(GH 3404)。

  • 在 pd.read_csv() 中,utf-xx 的别名(例如 UTF-xx、UTF_xx、utf_xx)引发了 UnicodeDecodeError。(GH 13549)

  • 在 pd.read_csv、pd.read_table、pd.read_fwf、pd.read_stata 和 pd.read_sas 中,如果 chunksize 和 iterator 都是 None,则解析器打开但未关闭文件。(GH 13940)

  • 在 StataReader、StataWriter、XportReader 和 SAS7BDATReader 中存在的 Bug,在出现错误时未正确关闭文件。(GH 13940)

  • 在 pd.pivot_table() 中,当 aggfunc 是列表时,会忽略 margins_name。(GH 13354)

  • 在 pd.Series.str.zfill、center、ljust、rjust 和 pad 中传递非整数时,未引发 TypeError。(GH 13598)

  • 在检查 TimedeltaIndex 中是否存在任何空对象时,始终返回 True。(GH 13603)

  • 在 Series 进行算术运算时,如果包含 object dtype 的日期时间,则引发 TypeError。(GH 13043)

  • 在 Series.isnull() 和 Series.notnull() 中忽略 Period('NaT')。(GH 13737)

  • 在 Series.fillna() 和 Series.dropna() 中不影响 Period('NaT')。(GH 13737)

  • 在 .fillna(value=np.nan) 中错误地在 category dtype 的 Series 上引发 KeyError。(GH 14021)

  • 在扩展 dtype 创建中存在的 Bug,创建的类型不是 / 不完全相同。(GH 13285)

  • 在 .resample(..) 中,IPython 内省错误地触发了不正确的警告。(GH 13618)

  • 在 NaT - Period 中引发 AttributeError。(GH 13071)

  • 在 Series 比较中,如果 rhs 包含 NaT,可能会输出错误的结果。(GH 9005)

  • 在 Series 和 Index 比较中,如果包含 object dtype 的 NaT,可能会输出不正确的结果。(GH 13592)

  • 在 Period 相加时,如果右侧是 Period,会引发 TypeError。(GH 13069)

  • 在 Period 和 Series 或 Index 比较中引发 TypeError。(GH 13200)

  • Bug in pd.set_eng_float_format() 会导致 NaN 和 Inf 的格式化失败(GH 11981)

  • 在 .unstack 中,使用 Categorical dtype 会重置 .ordered 为 True。(GH 13249)

  • 清理一些编译时警告在日期时间解析中(GH 13607)

  • 在factorize中存在错误,如果数据包含接近 DST 边界的日期时间,则会引发AmbiguousTimeError(GH 13750)

  • 在.set_index中存在错误,如果新索引包含 DST 边界和多级时会引发AmbiguousTimeError(GH 12920)

  • 在数据包含接近 DST 边界的日期时间时,使用.shift会引发AmbiguousTimeError的错误(GH 13926)

  • 在pd.read_hdf()中存在错误,当DataFrame具有categorical列且查询不匹配任何值时,返回的结果可能不正确(GH 13792)

  • 在使用非 lexsorted MultiIndex 进行索引时,使用.iloc存在错误(GH 13797)

  • 在使用日期字符串进行索引时,如果是逆排序的DatetimeIndex,在.loc中存在错误(GH 14316)

  • 在处理零维 NumPy 数组时,Series比较运算符存在错误(GH 13006)

  • 在.combine_first中存在错误,可能会返回不正确的dtype(GH 7630,GH 10567)

  • 在groupby中存在错误,如果apply返回的第一个结果是None,则返回结果会不同(GH 12824)

  • 在groupby(..).nth()中存在错误,如果在.head()/.tail()之后调用,组键的包含方式会不一致(GH 12839)

  • 在.to_html、.to_latex和.to_string中存在错误,通过formatters关键字传递的自定义日期时间格式化程序会被静默忽略(GH 10690)

  • 在DataFrame.iterrows()中存在错误,如果已定义但未生成Series子类,则不会生成(GH 13977)

  • 在使用pd.to_numeric时存在错误,当errors='coerce'且输入包含非可哈希对象时(GH 13324)

  • 在无效的Timedelta算术和比较中可能会引发ValueError而不是TypeError(GH 13624)

  • 在to_datetime和DatetimeIndex中存在无效日期时间解析的错误,可能会引发TypeError而不是ValueError(GH 11169,GH 11287)

  • 在使用时区感知的Timestamp创建的Index中存在错误,并且tz选项不匹配时,会错误地强制转换时区(GH 13692)

  • 在纳秒频率的DatetimeIndex中存在错误,不包括使用end指定的时间戳(GH 13672)

  • 在 Series 中存在 Bug,在使用 np.timedelta64 设置切片时 (GH 14155)

  • 在 Index 中存在 Bug,如果 datetime 超出 datetime64[ns] 的范围,则会引发 OutOfBoundsDatetime 错误,而不是强制转换为 object 数据类型 (GH 13663)

  • 在 Index 中存在 Bug,可能会忽略作为 dtype 传递的指定的 datetime64 或 timedelta64 (GH 13981)

  • 在 RangeIndex 中存在 Bug,可以创建无参数的 RangeIndex 而不是引发 TypeError (GH 13793)

  • .value_counts() 中存在 Bug,如果数据超出 datetime64[ns] 的范围,则会引发 OutOfBoundsDatetime 错误 (GH 13663)

  • 在 DatetimeIndex 中存在 Bug,如果输入的 np.datetime64 单位不是 ns,可能会引发 OutOfBoundsDatetime 错误 (GH 9114)

  • 在创建具有其他单位而不是 ns 的 np.datetime64 的 Series 时存在 Bug,将 object 数据类型结果设置为不正确的值 (GH 13876)

  • 在带有 timedelta 数据的 resample 中存在 Bug,数据被转换为浮点数 (GH 13119)

  • 使用 pd.isnull() 和 pd.notnull() 存在 Bug,如果输入的日期时间类型不是 ns 单位,则会引发 TypeError (GH 13389)

  • 在 pd.merge() 中存在 Bug,如果输入的日期时间类型不是 ns 单位,则可能会引发 TypeError (GH 13389)

  • 在 HDFStore/read_hdf() 中存在 Bug,如果设置了 tz,则会丢弃 DatetimeIndex.name (GH 13884)

  • Categorical.remove_unused_categories() 中存在 Bug,会将 .codes 的数据类型更改为平台整数 (GH 13261)

  • 在 groupby 中存在 Bug,使用 as_index=False 在多个列上进行分组时,包括一个分类列,会返回所有 NaN 值 (GH 13204)

  • 在 df.groupby(...)[...] 中存在 Bug,在使用 Int64Index 进行取项时可能会引发错误 (GH 13731)

  • 在为索引名称分配给 DataFrame.style 的 CSS 类中存在 Bug。先前它们被分配为 "col_heading level<n> col<c>",其中 n 是级别数 + 1。现在它们被分配为 "index_name level<n>",其中 n 是该 MultiIndex 的正确级别。

  • pd.read_gbq() 中存在 Bug,可能会引发 ImportError: No module named discovery,因为与另一个名为 apiclient 的 python 包存在命名冲突 (GH 13454)

  • 在 Index.union 中存在 Bug,在具有命名空索引的情况下返回错误的结果 (GH 13432)

  • 在 Python3 中,使用混合整数索引时,Index.difference 和 DataFrame.join 中存在错误 (GH 13432, GH 12814)

  • 将具有时区的 datetime.datetime 从具有时区的 datetime64 series 中减去的 bug (GH 14088)

  • 当 DataFrame 包含具有 NaN 值的标签的 MultiIndex 时,在 .to_excel() 中存在 bug (GH 13511)

  • 无效频率偏移字符串如 “D1”、“-2-3H” 可能不会引发 ValueError 的 bug (GH 13930)

  • 对于具有 RangeIndex 索引级别的分层框架,在 concat 和 groupby 中存在 bug (GH 13542)。

  • 对于只包含 object dtype 的 NaN 值的 Series,Series.str.contains() 中存在 bug (GH 14171)

  • 在 groupby dataframe 上的 agg() 函数中存在 bug,会将 datetime64[ns] 列的 dtype 更改为 float64 (GH 12821)

  • 使用 NumPy 的 ufunc 与 PeriodIndex 结合使用进行整数加法或减法会引发 IncompatibleFrequency 错误。建议使用标准运算符如 + 或 -,因为标准运算符使用更高效的路径 (GH 13980)

  • 在对 NaT 进行操作时返回 float 而不是 datetime64[ns] 的 bug (GH 12941)

  • 在具有 axis=None 时,Series 的灵活算术方法(如 .add())引发 ValueError 的 bug (GH 13894)

  • 在具有 MultiIndex 列的 DataFrame.to_csv() 中添加了多余的空行的 bug (GH 6618)

  • DatetimeIndex、TimedeltaIndex 和 PeriodIndex.equals() 中存在 bug,当输入不是 Index 但包含相同值时可能返回 True (GH 13107)

  • 在具有时区的 datetime 进行赋值时可能不起作用,如果它包含接近 DST 边界的 datetime (GH 14146)

  • 在 pd.eval() 和 HDFStore 查询中,使用 python 2 会截断长浮点数文字的 bug (GH 14241)

  • 当列不在 df 中且列包含重复值时,Index 中存在 bug,会引发 KeyError 并显示不正确的列 (GH 13822)

  • 当频率具有组合偏移别名时,Period 和 PeriodIndex 创建错误日期的 bug (GH 13874)

  • 在带有整数 line_width 和 index=False 的情况下调用 .to_string() 时会引发 UnboundLocalError 异常,因为 idx 在赋值之前被引用。

  • eval() 中的错误,resolvers 参数不接受列表(GH 14095)

  • stack、get_dummies、make_axis_dummies 中的错误,不会保留(多重)索引中的分类数据类型(GH 13854)

  • PeriodIndex 现在可以接受包含 pd.NaT 的 list 和 array(GH 13430)

  • df.groupby 中的错误,如果分组的数据框包含空箱,.median() 返回任意值(GH 13629)

  • Index.copy() 中的错误,name 参数被忽略(GH 14302)

贡献者

共有 117 人为此版本提供了补丁。带有“+”符号的人是首次贡献补丁的人。

  • Adrien Emery +

  • Alex Alekseyev

  • Alex Vig +

  • Allen Riddell +

  • Amol +

  • Amol Agrawal +

  • Andy R. Terrel +

  • Anthonios Partheniou

  • Ben Kandel +

  • Bob Baxley +

  • Brett Rosen +

  • Camilo Cota +

  • Chris

  • Chris Grinolds

  • Chris Warth

  • Christian Hudon

  • Christopher C. Aycock

  • Daniel Siladji +

  • Douglas McNeil

  • Drewrey Lupton +

  • Eduardo Blancas Reyes +

  • Elliot Marsden +

  • Evan Wright

  • Felix Marczinowski +

  • Francis T. O’Donovan

  • Geraint Duck +

  • Giacomo Ferroni +

  • Grant Roch +

  • Gábor Lipták

  • Haleemur Ali +

  • Hassan Shamim +

  • Iulius Curt +

  • Ivan Nazarov +

  • Jeff Reback

  • Jeffrey Gerard +

  • Jenn Olsen +

  • Jim Crist

  • Joe Jevnik

  • John Evans +

  • John Freeman

  • John Liekezer +

  • John W. O’Brien

  • John Zwinck +

  • Johnny Gill +

  • Jordan Erenrich +

  • Joris Van den Bossche

  • Josh Howes +

  • Jozef Brandys +

  • Ka Wo Chen

  • Kamil Sindi +

  • Kerby Shedden

  • Kernc +

  • Kevin Sheppard

  • Matthieu Brucher +

  • Maximilian Roos

  • Michael Scherer +

  • Mike Graham +

  • Mortada Mehyar

  • Muhammad Haseeb Tariq +

  • Nate George +

  • Neil Parley +

  • Nicolas Bonnotte

  • OXPHOS

  • Pan Deng / Zora +

  • Paul +

  • Paul Mestemaker +

  • Pauli Virtanen

  • Pawel Kordek +

  • Pietro Battiston

  • Piotr Jucha +

  • Ravi Kumar Nimmi +

  • Robert Gieseke

  • Robert Kern +

  • Roger Thomas

  • Roy Keyes +

  • Russell Smith +

  • Sahil Dua +

  • Sanjiv Lobo +

  • Sašo Stanovnik +

  • Shawn Heide +

  • Sinhrks

  • Stephen Kappel +

  • Steve Choi +

  • Stewart Henderson +

  • Sudarshan Konge +

  • Thomas A Caswell

  • Tom Augspurger

  • Tom Bird +

  • Uwe Hoffmann +

  • WillAyd +

  • Xiang Zhang +

  • YG-Riku +

  • Yadunandan +

  • Yaroslav Halchenko

  • Yuichiro Kaneko +

  • adneu

  • agraboso +

  • babakkeyvani +

  • c123w +

  • chris-b1

  • cmazzullo +

  • conquistador1492 +

  • cr3 +

  • dsm054

  • gfyoung

  • harshul1610 +

  • iamsimha +

  • jackieleng +

  • mpuels +

  • pijucha +

  • priyankjain +

  • sinhrks

  • wcwagner +

  • yui-knk +

  • zhangjinjie +

  • znmean +

  • 颜发才(Yan Facai) +

posted @ 2024-06-26 10:37  绝不原创的飞龙  阅读(97)  评论(0)    收藏  举报