拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Pandas 0.15.2 版本全解析:MultiIndex 扩展索引、Categorical 互操作与关键 API 变更

Pandas 0.15.2 版本全解析MultiIndex 扩展索引、Categorical 互操作与关键 API 变更【免费下载链接】pandasFlexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more项目地址: https://gitcode.com/gh_mirrors/pa/pandas导读本文基于 doc/source/whatsnew/v0.15.2.rst发布于 2014 年 12 月 12 日系统梳理 pandas 0.15.2 这一从 0.15.1 出发的小版本更新它包含大量 Bug 修复、若干新特性与增强、以及为修复既有问题而必须引入的一小部分 API 变更。读完本文你将掌握 MultiIndex 超出字典序深度的索引行为、Categorical 与 Stata/HDF5 的互操作能力、all/any聚合的新参数语义、to_datetime的exact匹配控制以及一批直接影响日常数据清洗与 I/O 的细节变更并了解这些特性在当前仓库源码中的实现落点。版本背景与升级建议pandas 0.15.2 是一个从 0.15.1 出发的小版本发布官方建议所有用户升级到该版本。该版本的主要特点包括大量 Bug 修复涉及索引、时间序列、I/O、绘图、分组聚合等几乎所有核心模块若干新特性与增强以Categorical类型为中心的外部存储互操作以及all/any、to_datetime、Timedelta等 API 的扩充少量 API 变更这些变更并非为了引入新功能而是为了修复既有 Bug 而必须做出的行为调整使用旧行为编写的代码需要关注迁移。版本公告按 4 个板块组织本文依此展开Enhancements增强API ChangesAPI 变更Performance Improvements性能改进Bug FixesBug 修复API changes本节收录的是会改变既有行为、需要使用者留意迁移的变更其中大多数是为了消除不一致行为而做的修正。MultiIndex支持超出字典序深度的索引这是本版本最重要的 API 变更之一。此前当MultiIndex未按字典序lexicographic order排序时通过.loc对多级索引做部分键查找会直接抛出KeyError0.15.2 起这一限制被解除——只要键位于已排序的前若干级即lexsort_depth之内即可工作但字典序排序的索引在性能上更优因此未排序索引上做此类查找会给出PerformanceWarning。来看官方文档给出的完整示例import numpy as np import pandas as pd df pd.DataFrame( { jim: [0, 0, 1, 1], joe: [x, x, z, y], jolie: np.random.rand(4), } ).set_index([jim, joe]) df # jolie # jim joe # 0 x 0.126970 # x 0.966718 # 1 z 0.260476 # y 0.897237此时索引的字典序深度只有 1第一级jim有序第二级joe在jim 1分组内不是有序的df.index.lexsort_depth # 1 # 在 0.15.2 之前的版本中这会抛 KeyError # 现在会给出 PerformanceWarning df.loc[(1, z)] # jolie # jim joe # 1 z 0.260476而对索引做字典序排序之后lexsort_depth变为 2查找同样成立且性能更优df2 df.sort_index() df2 # jolie # jim joe # 0 x 0.126970 # x 0.966718 # 1 y 0.897237 # z 0.260476 df2.index.lexsort_depth # 2 df2.loc[(1, z)] # jolie # jim joe # 1 z 0.260476源码实现落点当前仓库中lexsort_depth的语义被完整保留。MultiIndex._lexsort_depth属性缓存了该值若sortorder已记录则直接复用否则调用模块级函数_lexsort_depth(codes, nlevels)计算见 pandas/core/indexes/multi.py。底层实现从最高层向低层逐级调用 Cython 的libalgos.is_lexsorted判断前 k 层是否已字典序有序见 pandas/core/indexes/multi.py。在部分键查找路径_partial_tup_index中如果键的长度超过_lexsort_depth会抛出UnsortedIndexError见 pandas/core/indexes/multi.py而在非字典序索引上做drop且未指定level时会按mode.performance_warnings配置发出PerformanceWarning见 pandas/core/indexes/multi.py。相关行为在 pandas/tests/indexes/multi/test_lexsort.py、pandas/tests/indexes/multi/test_sorting.py 与 pandas/tests/indexing/multiindex/test_slice.py 中有大量覆盖。Categorical.unique只返回实际出现的类别此前对Categorical调用unique()会返回全部声明的 categories无论这些类别是否真的出现在数据中例如cat pd.Categorical([a, b, a], categories[a, b, c]) cat # [a, b, a] # Categories (3, object): [a b c] cat.unique() # 旧行为array([a, b, c], dtypeobject) - 错误包含了未使用的 c0.15.2 起unique()只返回数据中实际出现的类别同时保留声明的类别全集信息 cat pd.Categorical([a, b, a], categories[a, b, c]) cat.unique() [a, b] Categories (3, str): [a, b, c]当前实现中Categorical.unique()委托父类返回“categories 与 codes 均去重”的Categorical见 pandas/core/arrays/categorical.py其 docstring 示例明确展示了未使用类别不会出现在结果中。Series/Index 的 all 与 any参数语义调整Series.all与Series.any新增支持level与skipna参数同时为 ndarray 兼容而存在的out与keepdims参数被移除。此外各类Index不再支持all/any聚合函数调用将抛出TypeError。这一变更由 pandas/tests/series/test_reductions.py 等测试验证。源码实现落点当前仓库中NDFrame.all/any的签名只有axis、bool_only、skipna和**kwargs统一经由_logical_func分发到nanops.nanall/nanops.nanany见 pandas/core/generic.py任何多余的命名参数都会在_logical_func中被nv.validate_logical_func拒绝。Categorical 与 object 的相等比较允许带categorydtype 的Series与objectdtype 的Series做相等性比较此前这种比较会抛出TypeError。NDFrame属性与列名冲突行为一致化当 DataFrame 同时存在名为y的属性与列时读写行为此前是不一致的data.y返回属性而data.y z却更新列。0.15.2 起两者统一为操作列 data pd.DataFrame({x: [1, 2, 3]}) data.y 2 data[y] [2, 4, 6] data x y 0 1 2 1 2 4 2 3 6 data.y 5 # 此前这一赋值行为不一致旧行为读返回属性、写更新列In [6]: data.y Out[6]: 2 In [7]: data[y].values Out[7]: array([5, 5, 5])新行为读与写都作用于列 data.y 5 data[y].values array([2, 4, 6])Timestamp(now) / Timestamp(today) 语义修正Timestamp(now)现在等价于Timestamp.now()返回本地时间而非 UTCTimestamp(today)现在等价于Timestamp.today()且两者都接受可选的tz参数。标签切片支持负步长此前s.loc[c:a:-1]这类基于标签的负步长切片无法正确工作只返回单个元素。0.15.2 起行为修正# 旧行为 In [1]: s pd.Series(np.arange(3), [a, b, c]) In [2]: s.loc[c:a:-1] Out[2]: c 2 dtype: int64 # 新行为 s pd.Series(np.arange(3), [a, b, c]) s.loc[c:a:-1] c 2 b 1 a 0 dtype: int64相关切片逻辑在当前仓库的 pandas/core/indexes/multi.py 等实现中均对step is not None的情况做了分支处理。增强Enhancements本版本以Categorical为核心展开了多项 I/O 互操作能力并对时间类型、SQL 写出、字符串解析等做了增强。Categorical 增强导出到 Stata 数据文件新增将Categorical数据导出到 Stata 文件的能力。导出时类别编码作为整型数据值写入、类别本身作为 value labels 写入。需要注意的限制详见 doc/source/user_guide/io.rstStata 没有与Categorical完全对应的类型导出时会丢失变量是否为有序ordered的信息Stata 仅支持字符串型 value labels因此导出时会对类别调用str()若类别为非字符串类型会给出警告且当str()表示不唯一时可能造成信息丢失。从 Stata 导入order_categoricals 参数StataReader与read_stata新增布尔参数order_categoricals默认True用于控制导入的 Categorical 变量是否保序。官方用户指南doc/source/user_guide/io.rst对导入细节说明如下带标签数据默认通过convert_categoricalsTrue导入为Categorical导入时 Stata 文件中的原始值并不保留Categorical一律使用-1到n-1的整型编码缺失值编码为-1原始值按升序依次映射到0, 1, ..., n-1如需原始数值可设convert_categoricalsFalse此时不再导入变量标签若原始 Stata 值是带标签的整型且确实是有序的导入后order_categoricalsTrue会保留序数信息。源码实现落点order_categoricals贯穿整个 Stata 读取链路——StataReader构造参数见 pandas/io/stata.py、read_stata顶层参数见 pandas/io/stata.py最终在_convert_categoricals中决定Categorical(..., orderedorder_categoricals)见 pandas/io/stata.py。相关行为由 pandas/tests/io/test_stata.py 覆盖。导出到/从 HDF5新增categorydtype 数据写入HDFStore的能力见 doc/source/user_guide/io.rst查询方式与 object 数组一致但与普通 object 列不同、、、这类排序比较要求列以orderedTrue写出且比较依据的是类别顺序而非值本身categorydtype 数据的存储方式更高效。官方示例dfcat pd.DataFrame( {A: pd.Series(list(aabbcdba)).astype(category), B: np.random.randn(8)} ) cstore pd.HDFStore(cats.h5, modew) cstore.append(dfcat, dfcat, formattable, data_columns[A]) result cstore.select(dfcat, whereA in [b, c]) cstore.close()Categorical.searchsorted()Categorical类新增searchsorted()支持可在类别编码上执行二分查找定位插入位置。其他增强to_sql 支持自定义 SQL 列类型写 DataFrame 到数据库时新增指定各列 SQL 类型的能力默认字符串列使用Text类型。例如使用 SQLAlchemy 的String类型from sqlalchemy.types import String data.to_sql(data_dtype, engine, dtype{Col_1: String})同时to_sql现在会为含有 NA 值且 dtype 为object的列依据非 NA 值推断数据类型。sql_schema也改为生成方言适配的CREATE TABLE语句。Series.all / Series.any 的 level 与 skipnaSeries.all/Series.any支持按索引层级分组聚合 s pd.Series([False, True, False], index[0, 0, 1]) s.any(level0) 0 True 1 False dtype: boolPanel 支持 all / anyPanel新增all()/any()聚合函数基于随机布尔数组的示例输出 p pd.Panel(np.random.rand(2, 5, 4) 0.1) p.all() 0 1 2 3 0 True True True True 1 True False True True 2 True True True True 3 False True False True 4 True True True TrueTimestamp 类增强Timestamp新增utcfromtimestamp()、fromtimestamp()、combine()方法。Timedelta 算术与 API 增强Timedelta在未知情况下参与算术运算时返回NotImplemented从而允许自定义类扩展其行为Timedelta支持与合适 dtype 的numpy.ndarray对象做算术运算仅限 numpy 1.8 及以上新增Timedelta.to_timedelta64()公开方法。to_datetime 的 exact 参数to_datetime新增exact关键字当exactFalse时传入的format字符串不必与输入完全匹配exact默认值为True即默认仍要求精确匹配。这在需要部分匹配格式字符串的宽松解析场景下非常实用同时官方明确该路径有独立的性能优化见下文性能章节。源码实现落点当前仓库中to_datetime签名包含exact: bool True并说明“exact format matching behavior from to_datetime”见 pandas/core/tools/datetimes.py。解析时由array_strptime(arg, fmt, exactexact, ...)接手若使用exactFalse会对格式做截断处理。其他小增强pandas.io.gaGoogle Analytics 数据读取补充了基础文档gbq模块新增gbq.generate_bq_schema()函数用于生成 BigQuery schemaSeries现在可以像接受生成器一样接受 map 对象HDFStore新增上下文管理器支持可自动关闭存储with pd.HDFStore(store.h5) as store: ...parallel_coordinates绘图函数新增axvlines布尔选项控制是否绘制纵向参考线默认Trueread_html新增读取表格 footer表脚注的能力。性能改进Performance本版本的两项性能优化都与解析和转换热路径相关read_csv的skiprows为整数时减少内存占用。此前以整数形式跳过行时会在内存中保留不必要的中间数据现在改为更节约的内存路径。to_datetime转换提速在传入format且exactFalse的场景下转换性能得到提升。exactFalse允许格式字符串部分匹配输入实现上可以对已知格式做更快的字符串切分解析避免逐字符兜底匹配。Bug Fixes0.15.2 修复了大量 Bug按模块归纳如下便于定位与回归验证Categorical 与类型系统concat拼接categorydtype 的Series时被错误强制为object此前 bugcummin/cummax在含NaT的datetime64Series 上抛出ValueErrorget_data_google返回 object dtype、DataReader在含缺失值时返回 object dtypeto_datetime解析%f纳秒格式错误、Timestamp无法解析 UTC 的Z时区设计符TimedeltaIndex构造时传入单位被重复应用纳秒换算单位被应用两次Timedelta关键字参数现在支持 numpy 整型与浮点型修复了Timedelta算术与比较的多处问题日期类操作Timestamp - Timestamp未返回Timedelta、带时区的 datelike-datelike 操作时区不匹配异常统一为TypeError此前个别场景为ValueError。MultiIndex 与索引用空列表 至少一个布尔索引器切片 MultiIndex 出错MultiIndex.reindex在 level 上重排时标签未正确重排MultiIndex.__contains__在索引非字典序或非唯一时返回错误结果DataFrame.stack(..., dropnaFalse)在列 MultiIndex 的 labels 未引用全部 levels 时出错多列 stack 时 level 名为数字部分或全部导致出错DatetimeIndex使用time对象作为键出错。合并 / 分组 / 重采样merge(howleft, sortFalse)未保持左表顺序pd.Grouper(key...)无 level/axis 或仅 level 时出错groupby 传入非法/无参数时改为抛TypeErrorgroupby签名缺失*args/**kwargsresample跨多天重采样且最后偏移量不是从范围起点计算时抛ValueError。I/OStataWriter写入的字符串固定为 244 字符与真实大小不符to_html(indexFalse)输出 MultiIndex 时多出一列read_csv跳过行中行尾空白处理错误Python 3 下读取大 CSV 文件时除以 0CSV 解析中 dtype 与 names 不匹配时错误信息不清晰sql_schema现在生成方言适配的CREATE TABLEio.data.Options在 Yahoo 无到期日或收不到数据时抛RemoteDataError。时间序列 / 时区pd.infer_freq/DataFrame.inferred_freq在索引包含 DST 日时无法推断亚日频率DatetimeIndex迭代在 Fixed/Local offset 时区下出现回归dateutil 2.3 下的若干操作问题。绘图 / 其他字体大小只在垂直时设置 x 轴、水平时设置 y 轴相反方向未设置DataFrame.plot(kindscatter)检查 np.array 是否在 DataFrame 中时失败绘图时use_indexFalse仍使用索引名sharex开启且索引为时间序列时多轴重复显示标签period 类数组绘图出错matplotlib 1.2 时跳过直方图测试BlockManager中设置不同类型值会破坏 block 完整性NDFrame.size属性补齐以兼容 numpy 1.9.1此前与np.array_split配合出错选项上下文管理器在__enter__上就生效slice字符串方法现在考虑步长str.slice步长支持、Timedelta相关修复等修复了用py2app/cx_Freeze打包 pandas 的问题。这些修复大多对应公开 issue 编号如 8559、2646、8302、8994、9000、8753、8633、8836、7621、8420、8778、8904、8681 等可在 pandas 的 issue 追踪系统中回溯讨论与复现细节。小结pandas 0.15.2 虽然在版本号上只是一个小版本却横跨了索引语义MultiIndex 非字典序查找、类型系统Categorical 的unique语义与 Stata/HDF5 互操作、聚合 APIall/any参数重构、时间类型Timestamp/Timedelta语义修正以及数十处细节 Bug 修复。其中许多行为如lexsort_depth、order_categoricals、to_datetime(exact...)至今仍保留在当前仓库的实现中是理解 pandas 索引优化策略与类型互操作设计的重要历史节点。如果你正在维护基于 pandas 的存量代码建议重点核对本文“API changes”一节涉及的四类行为变更它们会直接影响索引查找、聚合结果与 I/O 读取的返回值其余增强与性能项则可按需升级使用。【免费下载链接】pandasFlexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more项目地址: https://gitcode.com/gh_mirrors/pa/pandas创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门