版本 0.12.0 (2013年7月24日)#
这是 0.11.0 的一个重要版本,包含了一些新特性和增强功能,以及大量的 bug 修复。
主要亮点包括:统一的 I/O API 命名方案、读取 HTML 的例程、将 MultiIndex 写入 CSV 文件、读写 STATA 数据文件、读写 JSON 格式文件、HDFStore
的 Python 3 支持、通过 filter
过滤 groupby 表达式,以及经过改进的支持正则表达式的 replace
例程。
API 变更#
I/O API 现在更加一致,提供了一组顶层
reader
函数,例如通过pd.read_csv()
访问,这些函数通常返回一个pandas
对象。
read_csv
read_excel
read_hdf
read_sql
read_json
read_html
read_stata
read_clipboard
对应的
writer
函数是对象方法,通过df.to_csv()
访问
to_csv
to_excel
to_hdf
to_sql
to_json
to_html
to_stata
to_clipboard
修复 Series 和 DataFrame 上的模运算和整数除法,使其行为类似于
float
数据类型,适当地返回np.nan
或np.inf
(GH 3590)。这纠正了 numpy 将integer
和float
数据类型区别对待的错误。In [1]: p = pd.DataFrame({"first": [4, 5, 8], "second": [0, 0, 3]}) In [2]: p % 0 Out[2]: first second 0 NaN NaN 1 NaN NaN 2 NaN NaN In [3]: p % p Out[3]: first second 0 0.0 NaN 1 0.0 NaN 2 0.0 0.0 In [4]: p / p Out[4]: first second 0 1.0 NaN 1 1.0 NaN 2 1.0 1.0 In [5]: p / 0 Out[5]: first second 0 inf NaN 1 inf NaN 2 inf inf向
groupby
添加squeeze
关键字,如果组是唯一的,则允许从 DataFrame -> Series 进行归约。这是 0.10.1 版本的一个回归。我们正在恢复到之前的行为。这意味着无论组是否唯一,groupby 都将返回相同形状的对象。撤销此问题 (GH 2893) 并修复 (GH 3596)。In [2]: df2 = pd.DataFrame([{"val1": 1, "val2": 20}, ...: {"val1": 1, "val2": 19}, ...: {"val1": 1, "val2": 27}, ...: {"val1": 1, "val2": 12}]) In [3]: def func(dataf): ...: return dataf["val2"] - dataf["val2"].mean() ...: In [4]: # squeezing the result frame to a series (because we have unique groups) ...: df2.groupby("val1", squeeze=True).apply(func) Out[4]: 0 0.5 1 -0.5 2 7.5 3 -7.5 Name: 1, dtype: float64 In [5]: # no squeezing (the default, and behavior in 0.10.1) ...: df2.groupby("val1").apply(func) Out[5]: val2 0 1 2 3 val1 1 0.5 -0.5 7.5 -7.5在使用基于标签的索引器掩码(例如布尔 Series)进行布尔索引时,即使带有整数标签,
iloc
也会引发错误。由于iloc
纯粹基于位置,Series 上的标签无法对齐 (GH 3631)这种情况很少使用,并且有许多替代方法。这保留了
iloc
API 纯粹基于位置的特性。In [6]: df = pd.DataFrame(range(5), index=list("ABCDE"), columns=["a"]) In [7]: mask = df.a % 2 == 0 In [8]: mask Out[8]: A True B False C True D False E True Name: a, dtype: bool # this is what you should use In [9]: df.loc[mask] Out[9]: a A 0 C 2 E 4 # this will work as well In [10]: df.iloc[mask.values] Out[10]: a A 0 C 2 E 4
df.iloc[mask]
将引发ValueError
。绘图函数的
raise_on_error
参数已移除。相反,当对象的dtype
是object
时,绘图函数会引发TypeError
,以提醒您尽可能避免使用object
数组,因此如果您需要绘图,应该将其转换为适当的数值数据类型。向 DataFrame 绘图方法添加
colormap
关键字。接受 matplotlib 颜色映射对象(例如,matplotlib.cm.jet)或此类对象的字符串名称(例如,'jet')。颜色映射被采样以选择每个列的颜色。有关更多信息,请参阅 颜色映射。( GH 3860)
DataFrame.interpolate()
现已弃用。请改用DataFrame.fillna()
和DataFrame.replace()
。( GH 3582, GH 3675, GH 3676)
DataFrame.replace()
的method
和axis
参数已弃用。
DataFrame.replace
的infer_types
参数已移除,现在默认执行转换。( GH 3907)向
DataFrame.insert
添加关键字allow_duplicates
,如果为True
,则允许插入重复列,默认值为False
(与 0.12 之前相同)( GH 3679)IO API
添加了顶层函数
read_excel
以替代以下内容,原始 API 已弃用,将在未来版本中移除from pandas.io.parsers import ExcelFile xls = ExcelFile("path_to_file.xls") xls.parse("Sheet1", index_col=None, na_values=["NA"])随着
import pandas as pd pd.read_excel("path_to_file.xls", "Sheet1", index_col=None, na_values=["NA"])添加了顶层函数
read_sql
,其功能等同于以下内容from pandas.io.sql import read_frame read_frame(...)
DataFrame.to_html
和DataFrame.to_latex
现在接受路径作为第一个参数 (GH 3702)不允许
datetime64[ns]
转换为其他类型,除了object
;timedelta64[ns]
仅允许转换为object/int
(GH 3425)
datetime64
数据类型的行为在某些所谓的归约操作方面有所改变 (GH 3726)。以下操作现在在Series
上执行时会引发TypeError
,而在DataFrame
上执行时则返回一个空的Series
,类似于在例如slice
对象的DataFrame
上执行这些操作。
sum, prod, mean, std, var, skew, kurt, corr, and cov
read_html
现在在读取时默认为None
,当 lxml 解析失败时,会回退到bs4
+html5lib
。尝试多个解析器直到成功也是有效的。内部
pandas
类层次结构已(略微)改变。以前的PandasObject
现在被称为PandasContainer
,一个新的PandasObject
成为了PandasContainer
以及Index
,Categorical
,GroupBy
,SparseList
, 和SparseArray
(以及它们的基类)的基类。目前,PandasObject
提供了字符串方法(来自StringMixin
)。(GH 4090, GH 4092)新的
StringMixin
,给定一个__unicode__
方法,可以获得与 python 2 和 python 3 兼容的字符串方法(__str__
、__bytes__
和__repr__
)。此外,还提供了全面的字符串安全性。现在广泛应用于 pandas 库的许多地方。( GH 4090, GH 4092)
IO 增强功能#
pd.read_html()
现在可以解析 HTML 字符串、文件或 URL 并返回 DataFrame,这要感谢 @cpcloud。( GH 3477, GH 3605, GH 3606, GH 3616)。它与单个解析器后端配合使用:BeautifulSoup4 + html5lib 参阅文档你可以使用
pd.read_html()
读取DataFrame.to_html()
的输出,如下所示:In [11]: df = pd.DataFrame({"a": range(3), "b": list("abc")}) In [12]: print(df) a b 0 0 a 1 1 b 2 2 c In [13]: html = df.to_html() In [14]: alist = pd.read_html(html, index_col=0) In [15]: print(df == alist[0]) a b 0 True True 1 True True 2 True True请注意,这里的
alist
是 Python 的list
,所以pd.read_html()
和DataFrame.to_html()
并非互逆操作。
pd.read_html()
不再对日期字符串执行硬转换 (GH 3656)。警告
您可能需要安装旧版本的 BeautifulSoup4,请参阅安装文档
添加了用于读写 Stata 文件的模块:
pandas.io.stata
(GH 1512),可通过顶层函数read_stata
进行读取,并通过 DataFrame 方法to_stata
进行写入。请参阅文档添加了用于读写 JSON 格式文件的模块:
pandas.io.json
,可通过顶层函数read_json
进行读取,并通过 DataFrame 方法to_json
进行写入。请参阅文档,解决了各种问题 (GH 1226, GH 3804, GH 3876, GH 3867, GH 1305)对 CSV 格式文件读写的
MultiIndex
列支持。
read_csv
中的header
选项现在接受一个列表,该列表指定要读取索引的行。选项
tupleize_cols
现在可以在to_csv
和read_csv
中指定,以提供与 0.12 之前版本兼容的行为,即通过元组列表写入和读取MultIndex
列。0.12 版本的默认行为是写入元组列表,并且不将元组列表解释为MultiIndex
列。注意:0.12 版本的默认行为与之前版本保持不变,但从 0.13 版本开始,写入和读取
MultiIndex
列的默认行为将采用新格式。( GH 3571, GH 1651, GH 3141)如果未指定
index_col
(例如,您没有索引,或者使用df.to_csv(..., index=False
写入),那么列索引上的任何names
都将丢失。In [16]: mi_idx = pd.MultiIndex.from_arrays([[1, 2, 3, 4], list("abcd")], names=list("ab")) In [17]: mi_col = pd.MultiIndex.from_arrays([[1, 2], list("ab")], names=list("cd")) In [18]: df = pd.DataFrame(np.ones((4, 2)), index=mi_idx, columns=mi_col) In [19]: df.to_csv("mi.csv") In [20]: print(open("mi.csv").read()) c,,1,2 d,,a,b a,b,, 1,a,1.0,1.0 2,b,1.0,1.0 3,c,1.0,1.0 4,d,1.0,1.0 In [21]: pd.read_csv("mi.csv", header=[0, 1, 2, 3], index_col=[0, 1]) Out[21]: c 1 2 d a b a Unnamed: 2_level_2 Unnamed: 3_level_2 1 1.0 1.0 2 b 1.0 1.0 3 c 1.0 1.0 4 d 1.0 1.0支持 Python3 上的
HDFStore
(通过PyTables 3.0.0
)通过
read_hdf
支持迭代器,当迭代完成时自动打开和关闭存储。这仅适用于表。In [25]: path = 'store_iterator.h5' In [26]: pd.DataFrame(np.random.randn(10, 2)).to_hdf(path, 'df', table=True) In [27]: for df in pd.read_hdf(path, 'df', chunksize=3): ....: print(df) ....: 0 1 0 0.713216 -0.778461 1 -0.661062 0.862877 2 0.344342 0.149565 0 1 3 -0.626968 -0.875772 4 -0.930687 -0.218983 5 0.949965 -0.442354 0 1 6 -0.402985 1.111358 7 -0.241527 -0.670477 8 0.049355 0.632633 0 1 9 -1.502767 -1.225492
read_csv
现在在文件不包含任何列(例如,只有换行符)时会抛出更具信息性的错误消息。
其他增强功能#
DataFrame.replace()
现在允许对包含object
数据类型的Series
使用正则表达式。请参阅常规文档中的示例部分:通过字符串表达式替换例如,你可以这样做:
In [22]: df = pd.DataFrame({"a": list("ab.."), "b": [1, 2, 3, 4]}) In [23]: df.replace(regex=r"\s*\.\s*", value=np.nan) Out[23]: a b 0 a 1 1 b 2 2 NaN 3 3 NaN 4用
NaN
替换所有字符串'.'
及其周围的零个或多个空白字符的出现。常规字符串替换仍然按预期工作。例如,你可以这样做
In [24]: df.replace(".", np.nan) Out[24]: a b 0 a 1 1 b 2 2 NaN 3 3 NaN 4用
NaN
替换所有字符串'.'
的出现。
pd.melt()
现在接受可选参数var_name
和value_name
来指定返回 DataFrame 的自定义列名。
pd.set_option()
现在允许 N 对选项-值 (GH 3667)。假设我们有一个选项
'a.b'
和另一个选项'b.c'
。我们可以同时设置它们:In [31]: pd.get_option('a.b') Out[31]: 2 In [32]: pd.get_option('b.c') Out[32]: 3 In [33]: pd.set_option('a.b', 1, 'b.c', 4) In [34]: pd.get_option('a.b') Out[34]: 1 In [35]: pd.get_option('b.c') Out[35]: 4组对象的
filter
方法返回原始对象的一个子集。假设我们只想获取属于组总和大于 2 的组中的元素。In [25]: sf = pd.Series([1, 1, 2, 3, 3, 3]) In [26]: sf.groupby(sf).filter(lambda x: x.sum() > 2) Out[26]: 3 3 4 3 5 3 dtype: int64
filter
的参数必须是一个函数,该函数应用于整个组时返回True
或False
。另一个有用的操作是过滤掉只包含少数成员的组中的元素。
In [27]: dff = pd.DataFrame({"A": np.arange(8), "B": list("aabbbbcc")}) In [28]: dff.groupby("B").filter(lambda x: len(x) > 2) Out[28]: A B 2 2 b 3 3 b 4 4 b 5 5 b或者,我们可以在不删除不符合过滤条件的组的情况下,返回一个具有相同索引的对象,其中不符合过滤条件的组填充为 NaN。
In [29]: dff.groupby("B").filter(lambda x: len(x) > 2, dropna=False) Out[29]: A B 0 NaN NaN 1 NaN NaN 2 2.0 b 3 3.0 b 4 4.0 b 5 5.0 b 6 NaN NaN 7 NaN NaNSeries 和 DataFrame 的 hist 方法现在接受
figsize
参数 (GH 3834)DatetimeIndex 在连接操作期间不再尝试转换混合整数索引 (GH 3877)
Timestamp.min 和 Timestamp.max 现在分别表示有效的 Timestamp 实例,而不是默认的 datetime.min 和 datetime.max,感谢 @SleepingPills。
当没有找到表且检测到 BeautifulSoup==4.2.0 时,
read_html
现在会引发错误 (GH 4214)
实验性功能#
添加了实验性
CustomBusinessDay
类,以支持带有自定义假期日历和自定义周掩码的DateOffsets
。( GH 2301)注意
这使用了 Numpy 1.7 中引入的
numpy.busdaycalendar
API,因此需要 Numpy 1.7.0 或更高版本。In [30]: from pandas.tseries.offsets import CustomBusinessDay In [31]: from datetime import datetime # As an interesting example, let's look at Egypt where # a Friday-Saturday weekend is observed. In [32]: weekmask_egypt = "Sun Mon Tue Wed Thu" # They also observe International Workers' Day so let's # add that for a couple of years In [33]: holidays = ["2012-05-01", datetime(2013, 5, 1), np.datetime64("2014-05-01")] In [34]: bday_egypt = CustomBusinessDay(holidays=holidays, weekmask=weekmask_egypt) In [35]: dt = datetime(2013, 4, 30) In [36]: print(dt + 2 * bday_egypt) 2013-05-05 00:00:00 In [37]: dts = pd.date_range(dt, periods=5, freq=bday_egypt) In [38]: print(pd.Series(dts.weekday, dts).map(pd.Series("Mon Tue Wed Thu Fri Sat Sun".split()))) 2013-04-30 Tue 2013-05-02 Thu 2013-05-05 Sun 2013-05-06 Mon 2013-05-07 Tue Freq: C, dtype: object
Bug 修复#
如果相关对象的 dtype 是
object
,绘图函数现在会在尝试绘图之前引发TypeError
(GH 1818, GH 3572, GH 3911, GH 3912),但如果可能,它们会尝试将 object 数组转换为数值数组,以便您仍然可以绘制例如包含浮点数的 object 数组。这发生在任何绘图操作之前,从而消除了任何虚假绘图的出现。如果
value
参数是列表或元组,fillna
方法现在会引发TypeError
。
Series.str
现在支持迭代 (GH 3638)。您可以迭代Series
中每个字符串的单个元素。每次迭代都会生成一个Series
,其中包含原始Series
的每个索引处的一个字符或NaN
。例如,In [38]: strs = "go", "bow", "joe", "slow" In [32]: ds = pd.Series(strs) In [33]: for s in ds.str: ...: print(s) 0 g 1 b 2 j 3 s dtype: object 0 o 1 o 2 o 3 l dtype: object 0 NaN 1 w 2 e 3 o dtype: object 0 NaN 1 NaN 2 NaN 3 w dtype: object In [41]: s Out[41]: 0 NaN 1 NaN 2 NaN 3 w dtype: object In [42]: s.dropna().values.item() == "w" Out[42]: True迭代器产生的最后一个元素将是一个
Series
,其中包含Series
中最长字符串的最后一个元素,所有其他元素均为NaN
。在这里,由于'slow'
是最长的字符串,并且没有其他长度相同的字符串,因此'w'
是生成的Series
中唯一的非空字符串。
HDFStore
非唯一索引支持已澄清 (GH 3468)。
修复在 DataFrame 中将新索引分配给重复索引时失败的问题 (GH 3468)
修复了构造具有重复索引的 DataFrame 的问题。
ref_locs 支持允许跨 dtype 的重复索引,使 iget 支持始终能够找到索引(即使跨 dtype)(GH 2194)
在具有非唯一索引的 DataFrame 上使用 applymap 现在可以正常工作(移除了警告)(GH 2786),并修复了 (GH 3230)
修复 to_csv 以处理非唯一列 (GH 3495)
通过 getitem 处理重复索引时将按正确顺序返回项目 (GH 3455, GH 3457),并像唯一索引一样处理缺失元素 (GH 3561)
通过 DataFrame.from_records 使用重复索引和空DataFrame将返回一个正确的DataFrame (GH 3562)
修复了当重复列跨越不同数据类型时,Concat 会产生非唯一列的问题 (GH 3602)
允许插入/删除到非唯一列 (GH 3679)
修复了通过
loc
及相关方法进行非唯一索引切片的问题 (GH 3659)允许插入/删除到非唯一列 (GH 3679)
扩展
reindex
以正确处理非唯一索引 (GH 3679)
DataFrame.itertuples()
现在可以与具有重复列名的 DataFrame 一起使用 (GH 3873)
iloc
在非唯一索引中的 bug 修复 (GH 4017);向reindex
添加了takeable
参数,用于基于位置的选取允许通过
.ix/.loc
和__getitem__
在 Series 中进行非唯一索引 (GH 4246)修复了
.ix/.loc
在非唯一索引中的内存分配问题 (GH 4280)
DataFrame.from_records
不接受空记录数组 (GH 3682)
read_html
现在可以正确跳过测试 (GH 3741)修复了
DataFrame.replace
中,当to_replace
参数中包含编译的正则表达式时无法正常工作的 bug (GH 3907)改进了
network
测试装饰器,以捕获IOError
(也因此捕获URLError
)。添加了with_connectivity_check
装饰器,允许显式检查网站以作为网络连接的代理。此外,还新增了optional_args
装饰器工厂,用于装饰器。( GH 3910, GH 3914)修复了测试问题,即打开了过多套接字,导致连接重置问题 (GH 3982, GH 3985, GH 4028, GH 4054)
修复了 test_yahoo、test_google 中测试失败的问题,其中符号未检索但被访问 (GH 3982, GH 3985, GH 4028, GH 4054)
Series.hist
如果未传入 figure,则将从当前环境中获取 figure。修复了 1xN DataFrame 在 1xN 掩码上崩溃的 bug (GH 4071)
修复了在 python3 下运行
tox
时 pickle 导入被以不兼容方式重写的问题 (GH 4062, GH 4063)修复了 sharex 和 sharey 未传递给 grouped_hist 的 bug (GH 4089)
修复了
DataFrame.replace
中当 regex=False 时嵌套字典未被迭代的 bug (GH 4115)修复了在使用
to_datetime
的format
参数时解析微秒的 bug (GH 4152)修复了
PandasAutoDateLocator
中invert_xaxis
错误触发MilliSecondLocator
的 bug (GH 3990)修复了 matplotlib 1.1.1 在无效颜色映射时未引发错误的绘图 bug (GH 4215)
修复了
DataFrame.plot(kind='kde')
中图例显示的问题 (GH 4216)修复了 Index 切片未携带 name 属性的 bug (GH 4226)
修复了在特定时区中使用字符串数组初始化
DatetimeIndex
的 bug (GH 4229)修复了 html5lib 未正确跳过的 bug (GH 4265)
修复了 get_data_famafrench 未使用正确文件边界的 bug (GH 4281)
请参阅 完整的发布说明 或 GitHub 上的问题跟踪器以获取完整列表。
贡献者#
共有 50 人为本次发布贡献了补丁。名字旁边带有“+”的人是首次贡献补丁。
Andy Hayden
Chang She (佘畅)
Christopher Whelan
Damien Garaud
Dan Allan
Dan Birken
Dieter Vandenbussche
Dražen Lučanin
Gábor Lipták +
Jeff Mellen +
Jeff Tratner +
Jeffrey Tratner +
Jonathan deWerd +
Joris Van den Bossche +
Juraj Niznan +
Karmel Allison
Kelsey Jordahl
Kevin Stone +
Kieran O’Mahony
Kyle Meyer +
Mike Kelly +
PKEuS +
Patrick O’Brien +
Phillip Cloud
Richard Höchenberger +
Skipper Seabold
SleepingPills +
Tobias Brandt
Tom Farnbauer +
TomAugspurger +
Trent Hauck +
Wes McKinney
Wouter Overmeire
Yaroslav Halchenko
conmai +
danielballan +
davidshinn +
dieterv77
duozhang +
ejnens +
gliptak +
jniznan +
jreback
lexual
nipunreddevil +
ogiaquino +
stonebig +
tim smith +
timmie
y-p