Pandas-2-2-中文文档-五十四-
Pandas 2.2 中文文档(五十四)
版本 0.19.2(2016 年 12 月 24 日)
这是 0.19.x 系列中的一个小 bug 修复版本,包括一些小的回归修复、bug 修复和性能改进。我们建议所有用户升级到此版本。
重点包括:
-
与 Python 3.6 兼容
-
添加了 Pandas Cheat Sheet。 (GH 13202)。
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 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)
-
.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 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 日)
这是从 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 日)
这是从 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
和DataFrame
API 更加一致。
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
关键字: -
顶层
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-aware
DateTimeIndex
上的.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) -
在
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) +