版本 0.12.0 (2013 年 7 月 24 日)#
这是 0.11.0 的一个主要版本,包含多个新功能、增强功能以及大量的错误修复。
主要亮点包括一致的 I/O API 命名方案、用于读取 html 的例程、将 MultiIndexes 写入 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
dtypes,根据情况返回np.nan
或np.inf
(GH 3590)。这纠正了一个 numpy 错误,该错误区别对待integer
和float
dtypes。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 3596) 恢复此问题 (GH 2893)。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
数组,因此如果您需要绘制某些内容,应将其转换为相应的数值 dtype。为 DataFrame 绘图方法添加
colormap
关键字。它接受 matplotlib colormap 对象(例如 matplotlib.cm.jet)或此类对象的字符串名称(例如 'jet')。 colormap 被采样以选择每列的颜色。请参阅Colormaps(色谱)了解更多信息。 (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]
执行 astypes 操作,除非转换为object在;对于
timedelta64[ns]
,只允许转换为object/int
(GH 3425)对于某些所谓的缩减操作 (GH 3726),
datetime64
dtypes 的行为已发生变化。当在Series
上执行时,以下操作现在会引发TypeError
;当在DataFrame
上执行时,会返回一个 空Series
,类似于在例如slice
对象的DataFrame
上执行这些操作。
sum, prod, mean, std, var, skew, kurt, corr 和 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 并返回 DataFrames,感谢 @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
是一个 Pythonlist
,所以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 版本之前通过元组列表写入和读取MultiIndex
列的行为的兼容性。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在 Python 3 上支持
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 dtype 的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或者,与其丢弃不符合条件的组,我们可以返回一个索引相似的对象,其中未通过过滤的组填充有 NaNs。
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)DatetimeIndexes 在连接操作期间不再尝试转换混合整数索引 (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
错误修复#
如果关联对象的 dtype 是
object
,绘图函数在尝试绘制任何内容之前现在会引发TypeError
(GH 1818, GH 3572, GH 3911, GH 3912),但如果可能,它们会尝试将 object 数组转换为数值数组,以便您仍然可以绘制例如包含浮点数的 object 数组。这发生在任何绘图开始之前,从而消除了显示任何虚假图。
fillna
方法现在在value
参数是列表或元组时引发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 支持允许跨 dtypes 的重复索引,允许 iget 支持始终找到索引(即使跨 dtypes)(GH 2194)
在带有非唯一索引的 DataFrame 上使用 applymap 现在可以工作(已移除警告)(GH 2786),并修复 (GH 3230)
修复了 to_csv 处理非唯一列的问题 (GH 3495)
带有 getitem 的重复索引将按正确顺序返回项 (GH 3455, GH 3457),并像唯一索引一样处理缺失元素 (GH 3561)
带有重复索引和空 DataFrame.from_records 将返回正确的帧 (GH 3562)
修复了当重复项跨越 dtypes 时,concat 会生成非唯一列的问题 (GH 3602)
允许对非唯一列进行插入/删除操作 (GH 3679)
修复了通过
loc
等方法使用切片进行非唯一索引的问题 (GH 3659)允许对非唯一列进行插入/删除操作 (GH 3679)
扩展
reindex
以正确处理非唯一索引 (GH 3679)带有重复列名的 DataFrame 现在可以使用
DataFrame.itertuples()
方法 (GH 3873)修复了通过
iloc
进行非唯一索引的 Bug (GH 4017);为reindex
添加了takeable
参数以进行基于位置的选择允许通过
.ix/.loc
和__getitem__
在 Series 中进行非唯一索引 (GH 4246)修复了使用
.ix/.loc
进行非唯一索引时的内存分配问题 (GH 4280)
DataFrame.from_records
不接受空 recarrays (GH 3682)
read_html
现在会正确跳过测试 (GH 3741)修复了一个 Bug,即在
to_replace
参数中使用编译后的正则表达式调用DataFrame.replace
无效的问题 (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
现在如果未传入图形对象,将从当前环境获取修复了 1xN DataFrame 在遇到 1xN 掩码时会出错的 bug(GH 4071)
修复了 python3 下运行
tox
时 pickle 导入被以不兼容方式重写的 bug(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 无效 colormap 未抛出异常的 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