版本 0.8.0 (2012年6月29日)#

这是从0.7.3版本以来的一个重大发布,包括对时间序列处理和基础设施的大量工作,以及整个库中大量新功能的加入。它包括来自20多位不同作者的700多次提交。大多数pandas 0.7.3及更早版本的用户在升级时不应遇到任何问题,但由于迁移到NumPy datetime64 dtype,可能潜伏着许多bug和不兼容问题。如果有必要,将在0.8.1版本中尽快修复残留的不兼容问题。请参阅 完整发布说明 或在GitHub上的问题跟踪器以获取完整列表。

对非唯一索引的支持#

所有对象现在都可以使用非唯一索引。数据对齐/连接操作根据SQL连接语义工作(包括,如果适用,在多对多连接中的索引重复)

NumPy datetime64 数据类型和 1.6 依赖项#

时间序列数据现在使用 NumPy 的 datetime64 dtype 表示;因此,pandas 0.8.0 现在至少需要 NumPy 1.6。它已经测试并验证可以使用 NumPy 的开发版本(1.7+),该版本包含一些重要的面向用户的 API 更改。NumPy 1.6 也有许多与纳秒分辨率数据相关的错误,所以我建议你避开 NumPy 1.6 的 datetime64 API 函数(尽管它们的功能有限),只使用 pandas 提供的接口与这些数据进行交互。

请参阅 0.8.0 部分的结尾,了解一个列出从 pandas 0.7 或更早版本迁移到 0.8.0 的旧代码库潜在问题的“移植”指南。

对于使用旧版 NumPy < 1.6 的用户,将为 0.7.x 系列提供必要的错误修复。0.7.x 版本将不再进行进一步的开发,仅提供错误修复。

时间序列的更改和改进#

备注

通过此版本,legacy scikits.timeseries 用户应该能够将他们的代码移植到使用 pandas。

备注

请参阅 文档 以了解 pandas 时间序列 API 的概述。

  • 新的 datetime64 表示 加快了连接操作和数据对齐减少了内存使用,并且在序列化/反序列化性能上显著优于 datetime.datetime。

  • 高性能且灵活的 resample 方法,用于从高频到低频和从低频到高频的转换。支持插值、用户定义的聚合函数,以及对区间和结果标签定义的控制。还实现了一系列高性能的 Cython/C 基础重采样函数(包括开盘-最高-最低-收盘)。

  • 频率别名 的改进以及对 频率快捷方式 的支持,例如 ‘15min’ 或 ‘1h30min’

  • 新的 DatetimeIndex 类 支持固定频率和不规则的时间序列。取代了现在已弃用的 DateRange 类

  • 新的 PeriodIndexPeriod 类用于表示 时间跨度 并执行 日历逻辑,包括 ``12 个财政季度频率 <timeseries.quarterly>`。这是对 scikits.timeseries 代码库元素的部分移植和实质性增强。支持在 PeriodIndex 和 DatetimeIndex 之间进行转换。

  • 新的时间戳数据类型子类 datetime.datetime ,提供相同的接口,同时启用处理纳秒分辨率数据。还提供 简单时区转换

  • 增强对 时区 的支持。为 TimeSeries 和 DataFrame 添加 tz_converttz_localize 方法。所有时间戳都存储为 UTC;设置了时区的 DatetimeIndex 对象的时间戳将被本地化到本地时间。因此,时区转换基本上是免费的。用户现在几乎不需要了解 pytz 库;只需要字符串形式的时区名称。只有当它们的 UTC 时间戳匹配时,时区感知的时间戳才相等。在不同时区的时间序列之间进行操作将产生一个 UTC 索引的时间序列。

  • 时间序列 字符串索引便利 / 快捷方式:按年份切片、年份和月份,以及用字符串索引值

  • 增强的时间序列 绘图;改编自 scikits.timeseries 基于 matplotlib 的绘图代码

  • 新的 date_rangebdate_rangeperiod_range 工厂函数

  • 强大的 频率推断 函数 infer_freq 和 DatetimeIndex 的 inferred_freq 属性,具有在构造 DatetimeIndex 时推断频率的选项

  • to_datetime 函数高效地将 字符串数组 解析为 DatetimeIndex。DatetimeIndex 将数组或字符串列表解析为 datetime64

  • 优化 对 Series 和 DataFrame 列中的 datetime64-dtype 数据的**支持**

  • 新的 NaT (Not-a-Time) 类型用于表示时间戳数组中的 NA

  • 优化 Series.asof 以查找时间戳数组的 “截至” 值

  • 毫秒、微秒、纳秒日期偏移对象

  • 可以使用 datetime.time 对象索引时间序列,以选择特定 一天中的时间 (TimeSeries.at_time) 或 两个时间之间 的数据 (TimeSeries.between_time)

  • 添加 tshift 方法,用于使用索引的频率(如果有)进行前导/滞后,而不是使用移位的简单前导/滞后。

其他新功能#

  • 新的 cutqcut 函数(类似于 R 的 cut 函数)用于通过将值分箱到基于值的(cut)或基于分位数的(qcut)箱中,从连续变量计算分类变量。

  • Factor 重命名为 Categorical 并添加了许多可用性功能

  • 添加 limit 参数到 fillna/reindex

  • 在 GroupBy 中更灵活的多功能应用,并且可以传递列表 (名称, 函数) 元组以按特定顺序获取具有给定名称的结果

  • 添加灵活的 替换 方法,以高效地替换值

  • 增强的 read_csv/read_table 用于读取时间序列数据并将多个列转换为日期

  • 注释 选项添加到解析器函数:read_csv 等。

  • 在解析函数中添加 dayfirst 选项以解析国际 DD/MM/YYYY 日期

  • 允许用户指定 CSV 读取器 方言 以控制引号等。

  • 在 read_csv 中处理 千位分隔符 以提高整数解析。

  • 启用一次性取消堆叠多个级别。缓解 pivot_table 错误(引入空列)

  • 切换到基于 klib 的哈希表进行索引;性能更好,内存使用比 Python 的字典更少。

  • 添加 first、last、min、max 和 prod 优化的 GroupBy 函数

  • 新的 ordered_merge 函数

  • 为 DataFrame, Series 添加灵活的 比较 实例方法 eq, ne, lt, gt 等。

  • 改进 scatter_matrix 绘图函数,并在对角线添加直方图或核密度估计

  • 为密度图添加 ‘kde’ 绘图选项

  • 通过 rpy2 支持将 DataFrame 转换为 R 的 data.frame

  • 在 Series 和 DataFrame 中改进了对复数的支持

  • pct_change 方法添加到所有数据结构中

  • 为 DataFrame 控制台输出添加 max_colwidth 配置选项

  • 插值 使用索引值的系列值

  • 可以从 GroupBy 中选择多列

  • 为 Series/DataFrame 添加 更新 方法,以便就地更新值

  • anyall 方法添加到 DataFrame

新的绘图方法#

import pandas as pd

fx = pd.read_pickle("data/fx_prices")
import matplotlib.pyplot as plt

Series.plot 现在支持 secondary_y 选项:

plt.figure()

fx["FR"].plot(style="g")

fx["IT"].plot(style="k--", secondary_y=True)

Vytautas Jancauskas,2012年GSOC的参与者,增加了许多新的绘图类型。例如,'kde' 是一个新选项:

s = pd.Series(
    np.concatenate((np.random.randn(1000), np.random.randn(1000) * 0.5 + 3))
)
plt.figure()
s.hist(density=True, alpha=0.2)
s.plot(kind="kde")

更多内容请参见 绘图页面

其他 API 更改#

  • 在时间序列函数中弃用 offsettime_ruletimeRule 参数名称。警告将持续打印,直到 pandas 0.9 或 1.0。

对于 pandas <= 0.7.3 用户的潜在移植问题#

在 pandas 0.8.0 中可能会影响你的主要变化是时间序列索引使用 NumPy 的 datetime64 数据类型,而不是 dtype=object 数组中的 Python 内置 datetime.datetime 对象。DateRange 已被 DatetimeIndex 取代,但其他方面表现相同。但是,如果你有将 DateRange 或包含 datetime.datetime 值的 Index 对象转换为普通 NumPy 数组的代码,由于你将控制权交给了 NumPy,使用标量值的代码可能存在潜在的错误。

In [1]: import datetime

In [2]: rng = pd.date_range("1/1/2000", periods=10)

In [3]: rng[5]
Out[3]: Timestamp('2000-01-06 00:00:00')

In [4]: isinstance(rng[5], datetime.datetime)
Out[4]: True

In [5]: rng_asarray = np.asarray(rng)

In [6]: scalar_val = rng_asarray[5]

In [7]: type(scalar_val)
Out[7]: numpy.datetime64

pandas 的 Timestamp 对象是 datetime.datetime 的一个子类,支持纳秒(nanosecond 字段存储0到999之间的纳秒值)。它应该可以直接替代任何之前使用 datetime.datetime 值的代码。因此,我建议不要将 DatetimeIndex 转换为常规的 NumPy 数组。

如果你有需要 datetime.datetime 对象数组的代码,你有几个选项。首先,DatetimeIndexastype(object) 方法会产生一个 Timestamp 对象数组:

In [8]: stamp_array = rng.astype(object)

In [9]: stamp_array
Out[9]: 
Index([2000-01-01 00:00:00, 2000-01-02 00:00:00, 2000-01-03 00:00:00,
       2000-01-04 00:00:00, 2000-01-05 00:00:00, 2000-01-06 00:00:00,
       2000-01-07 00:00:00, 2000-01-08 00:00:00, 2000-01-09 00:00:00,
       2000-01-10 00:00:00],
      dtype='object')

In [10]: stamp_array[5]
Out[10]: Timestamp('2000-01-06 00:00:00')

要获取一个合适的 datetime.datetime 对象数组,请使用 to_pydatetime 方法:

In [11]: dt_array = rng.to_pydatetime()

In [12]: dt_array
Out[12]: 
array([datetime.datetime(2000, 1, 1, 0, 0),
       datetime.datetime(2000, 1, 2, 0, 0),
       datetime.datetime(2000, 1, 3, 0, 0),
       datetime.datetime(2000, 1, 4, 0, 0),
       datetime.datetime(2000, 1, 5, 0, 0),
       datetime.datetime(2000, 1, 6, 0, 0),
       datetime.datetime(2000, 1, 7, 0, 0),
       datetime.datetime(2000, 1, 8, 0, 0),
       datetime.datetime(2000, 1, 9, 0, 0),
       datetime.datetime(2000, 1, 10, 0, 0)], dtype=object)

In [13]: dt_array[5]
Out[13]: datetime.datetime(2000, 1, 6, 0, 0)

matplotlib 知道如何处理 datetime.datetime 但不知道如何处理 Timestamp 对象。虽然我建议你使用 TimeSeries.plot 来绘制时间序列,但你可以使用 to_pydatetime 或为 Timestamp 类型注册一个转换器。更多信息请参见 matplotlib 文档

警告

在NumPy 1.6中,用户面对的API中存在与纳秒datetime64单位相关的错误。特别是,数组的字符串版本显示垃圾值,转换为``dtype=object``同样存在问题。

In [14]: rng = pd.date_range("1/1/2000", periods=10)

In [15]: rng
Out[15]: 
DatetimeIndex(['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04',
               '2000-01-05', '2000-01-06', '2000-01-07', '2000-01-08',
               '2000-01-09', '2000-01-10'],
              dtype='datetime64[ns]', freq='D')

In [16]: np.asarray(rng)
Out[16]: 
array(['2000-01-01T00:00:00.000000000', '2000-01-02T00:00:00.000000000',
       '2000-01-03T00:00:00.000000000', '2000-01-04T00:00:00.000000000',
       '2000-01-05T00:00:00.000000000', '2000-01-06T00:00:00.000000000',
       '2000-01-07T00:00:00.000000000', '2000-01-08T00:00:00.000000000',
       '2000-01-09T00:00:00.000000000', '2000-01-10T00:00:00.000000000'],
      dtype='datetime64[ns]')

In [17]: converted = np.asarray(rng, dtype=object)

In [18]: converted[5]
Out[18]: Timestamp('2000-01-06 00:00:00')

相信我:不要慌。如果你使用的是 NumPy 1.6 并且将你与 datetime64 值的交互限制在 pandas 的 API 内,你会没事的。数据类型本身没有问题(内部是一个 64 位整数);所有重要的数据处理都在 pandas 中进行,并且经过了大量测试。我强烈建议你 不要直接在 NumPy 1.6 中处理 datetime64 数组,只使用 pandas 的 API。

支持非唯一索引:在后一种情况下,您可能在 try:... catch: 块内的代码由于索引不唯一而失败。在许多情况下,它将不再失败(某些方法如 append 仍然检查唯一性,除非被禁用)。然而,并非一切都丢失了:您可以检查 index.is_unique 并在其为 False 时显式引发异常或进入不同的代码分支。

贡献者#

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

  • Adam Klein

  • Chang She

  • David Zaslavsky +

  • Eric Chlebek +

  • Jacques Kvam

  • Kamil Kisiel

  • Kelsey Jordahl +

  • Kieran O’Mahony +

  • Lorenzo Bolla +

  • Luca Beltrame

  • Marc Abramowitz +

  • Mark Wiebe +

  • Paddy Mullen +

  • Peng Yu +

  • Roy Hyunjin Han +

  • RuiDC +

  • Senthil Palanisami +

  • Skipper Seabold

  • Stefan van der Walt +

  • Takafumi Arakaki +

  • Thomas Kluyver

  • Vytautas Jancauskas +

  • Wes McKinney

  • Wouter Overmeire

  • Yaroslav Halchenko

  • thuske +

  • timmie +