您当前的位置:科技评论网资讯正文

从小白到大师这里有一份Pandas入门指南

放大字体  缩小字体 2019-08-15 12:58:15  阅读量:6256 作者:责任编辑NO。郑子龙0371

选自Medium

作者:Rudolf H hn

机器之心编译

参加:李诗萌、张倩

在本文中,作者从 Pandas 的简介开端,一步一步讲解了 Pandas 的开展现状、内存优化等问题。这是一篇最佳实践教程,既适宜用过 Pandas 的读者,也适宜没用过但想要上手的小白。

经过本文,你将有望发现一到多种用 pandas 编码的新办法。

本文包含以下内容:

Pandas 开展现状;

内存优化;

索引;

办法链;

随机提示。

在阅览本文时,我主张你阅览每个你不了解的函数的文档字符串(docstrings)。简略的 Google 查找和几秒钟 Pandas 文档的阅览,都会使你的阅览体会愈加愉快。

Pandas 的界说和现状

什么是 Pandas?

Pandas 是一个「开源的、有 BSD 开源协议的库,它为 Python 编程言语供给了高功用、易于运用的数据架构以及数据剖析东西」。总归,它供给了被称为 Dataframe 和 Series(对那些运用 Panel 的人来说,它们现已被弃用了)的数据笼统,经过办理索引来快速拜访数据、履行剖析和转化运算,乃至能够绘图(用 matplotlib 后端)。

Pandas 的当时最新版别是 v0.25.0 (https://github.com/pandas-dev/pandas/releases/tag/v0.25.0)

Pandas 正在逐渐升级到 1.0 版,而为了到达这一意图,它改动了许多人们习以为常的细节。Pandas 的中心开发者之一 Marc Garcia 宣布了一段十分风趣的讲演——「走向 Pandas 1.0」。

讲演链接:https:///watch?v=hK6o_TDXXN8

用一句话来总结,Pandas v1.0 首要改进了稳定性(如时刻序列)并删去了未运用的代码库(如 SparseDataframe)。

数据

让咱们开端吧!挑选「1985 到 2016 年间每个国家的自杀率」作为玩具数据集。这个数据集满足简略,但也足以让你上手 Pandas。

数据集链接:https:///russellyates88/suicide-rates-overview-1985-to-2016

在深入研究代码之前,假如你想重现成果,要先履行下面的代码预备数据,保证列名和类型是正确的。

提示:假如你读取了一个大文件,在 read_csv(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)中参数设定为 chunksize=N,这会回来一个能够输出 Dataframe 方针的迭代器。

这儿有一些关于这个数据集的描绘:

这儿有 101 个国家、年份从 1985 到 2016、两种性别、六个时代以及六个年纪组。有一些取得这些信息的办法:

能够用 unique() 和 nunique() 获取列内仅有的值(或仅有值的数量);

能够用 describe() 输出每一列不同的统计数据(例如最小值、最大值、平均值、总数等),假如指定 include='all',会针对每一列方针输出仅有元素的数量和呈现最多元素的数量;

能够用 head() 和 tail() 来可视化数据框的一小部分。

经过这些办法,你能够敏捷了解正在剖析的表格文件。

内存优化

在处理数据之前,了解数据并为数据框的每一列挑选适宜的类型是很重要的一步。

在内部,Pandas 将数据框存储为不同类型的 numpy 数组(比方一个 float64 矩阵,一个 int32 矩阵)。

有两种能够大幅下降内存耗费的办法。

Pandas 提出了一种叫做 memory_usage() 的办法,这种办法能够剖析数据框的内存耗费。在代码中,指定 deep=True 来保证考虑到了实践的体系运用状况。

memory_usage():https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Dataframe.memory_usage.html

了解列的类型(https://pandas.pydata.org/pandas-docs/stable/getting_started/basics.html#basics-dtypes)很重要。它能够经过两种简略的办法节约高达 90% 的内存运用:

了解数据框运用的类型;

了解数据框能够运用哪种类型来削减内存的运用(例如,price 这一列值在 0 到 59 之间,只带有一位小数,运用 float64 类型或许会发作不必要的内存开支)

除了下降数值类型的巨细(用 int32 而不是 int64)外,Pandas 还提出了分类类型:https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html

假如你是用 R 言语的开发人员,你或许觉得它和 factor 类型是相同的。

这种分类类型答运用索引替换重复值,还能够把实践值存在其他方位。教科书中的比方是国家。和屡次存储相同的字符串「瑞士」或「波兰」比起来,为什么不简略地用 0 和 1 替换它们,并存储在字典中呢?

Pandas 做了简直相同的作业,一同添加了一切的办法,能够实践运用这种类型,而且依然能够显现国家的称号。

回到 convert_df() 办法,假如这一列中的仅有值小于 50%,它会主动将列类型转化成 category。这个数是恣意的,可是由于数据框中类型的转化意味着在 numpy 数组间移动数据,因而咱们得到的有必要比失掉的多。

接下来看看数据中会发作什么。

经过运用「智能」转化器,数据框运用的内存简直削减了 10 倍(精确地说是 7.34 倍)。

索引

Pandas 是强壮的,但也需求支付一些价值。当你加载 Dataframe 时,它会创立索引并将数据存储在 numpy 数组中。这是什么意思?一旦加载了数据框,只需正确办理索引,就能够快速地拜访数据。

拜访数据的办法首要有两种,分别是经过索引和查询拜访。根据具体状况,你只能挑选其间一种。但在大多数状况中,索引(和多索引)都是最好的挑选。咱们来看下面的比方:

什么?加快 20 倍?

你要问自己了,创立这个多索引要多长时刻?

经过查询拜访数据的时刻是 1.5 倍。假如你只想检索一次数据(这种状况很少发作),查询是正确的办法。不然,你一定要坚持用索引,CPU 会为此感谢你的。

.set_index(drop=False) 答应不删去用作新索引的列。

.loc[]/.iloc[] 办法能够很好地读取数据框,但无法修正数据框。假如需求手动构建(比方运用循环),那就要考虑其他的数据结构了(比方字典、列表等),在预备好一切数据后,创立 Dataframe。不然,关于 Dataframe 中的每一个新行,Pandas 都会更新索引,这可不是简略的哈希映射。

因而,未排序的索引能够下降功用。为了查看索引是否现已排序并对它排序,首要有两种办法:

更多概况请参阅:

Pandas 高档索引用户攻略:https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html;

Pandas 库中的索引代码:https://github.com/pandas-dev/pandas/blob/master/pandas/core/indexing.py。

办法链

运用 Dataframe 的办法链是链接多个回来 Dataframe 办法的行为,因而它们都是来自 Dataframe 类的办法。在现在的 Pandas 版别中,运用办法链是为了不存储中心变量并防止呈现如下状况:

用下面的链替换:

说实话,第二段代码更美丽也更简练。

办法链的东西箱是由不同的办法(比方 apply、assign、loc、query、pipe、groupby 以及 agg)组成的,这些办法的输出都是 Dataframe 方针或 Series 方针(或 DataframeGroupBy)。

了解它们最好的办法便是实践运用。举个简略的比方:

取得每个年纪规模中一切仅有时代标签的简略链

在得到的数据框中,「年纪」列是索引。

除了了解到「X 代」覆盖了三个年纪组外,分化这条链。第一步是对年纪组分组。这一办法回来了一个 DataframeGroupBy 方针,在这个方针中,经过挑选组的仅有时代标签聚合了每一组。

在这种状况下,聚合办法是「unique」办法,但它也能够承受任何(匿名)函数。

在 0.25 版别中,Pandas 引入了运用 agg 的新办法:https://dev.pandas.io/whatsnew/v0.25.0.html#groupby-aggregation-with-relabeling。

用排序值(sort_values)和 head 得到自杀率排前十的国家和年份

用排序值 nlargest 得到自杀率排前十的国家和年份

在这些比方中,输出都是相同的:有两个目标(国家和年份)的 MultiIndex 的 Dataframe,还有包含排序后的 10 个最大值的新列 suicides_sum。

「国家」和「年份」列是索引。

nlargest(10) 比 sort_values(ascending=False).head(10) 更有用。

另一个风趣的办法是 unstack:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Dataframe.unstack.html,这种办法答应滚动索引水平。

「age」是索引,列「suicides_no」和「population」都有第二个水平列「sex」。

下一个办法 pipe 是最通用的办法之一。这种办法答应管道运算(就像在 shell 脚本中)履行比链更多的运算。

管道的一个简略但强壮的用法是记载不同的信息。

和 pipe 一同运用的不同记载函数。

举个比方,咱们想验证和 year 列比较,country_year 是否正确:

用来验证「country_year」列中年份的管道。

管道的输出是 Dataframe,但它也能够在规范输出(console/REPL)中打印。

你也能够在一条链顶用不同的 pipe。

女人自杀数量最高的国家和年份。

生成的 Dataframe 如下所示:

索引是「年份」和「国家」。

规范输出的打印如下所示:

除了记载到操控台外,pipe 还能够直接在数据框的列上运用函数。

自杀数量是否和 GDP 的下降相关?是否和性别相关?

上面的代码在操控台中的打印如下所示:

深入研究代码。norm_df() 将一个 Dataframe 和用 MinMaxScaling 扩展列的列表作为输入。运用字典了解,创立一个字典 ,然后将其解压为 assign() 函数的参数 (colunmn_name=method, …)。

在这种特别状况下,min-max 缩放不会改动对应的输出:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Dataframe.corr.html,它仅用于参数。

在(悠远的?)未来,缓式评价(lazy evaluation)或许呈现在办法链中,所以在链上做一些出资或许是一个好主意。

最终(随机)的技巧

下面的提示很有用,但不适用于前面的任何部分:

itertuples() 能够更高效地遍历数据框的行;

留意:tup 是一个 namedtuple

join() 用了 merge();

在 Jupyter 笔记本中,在代码块的最初写上 %%time,能够有用地丈量时刻;

UInt8 类:https://pandas.pydata.org/pandas-docs/stable/user_guide/gotchas.html#support-for-integer-na支撑带有整数的 NaN 值;

记住,任何密布的 I/O(例如打开大型 CSV 存储)用初级办法都会履行得更好(尽或许多地用 Python 的中心函数)。

还有一些本文没有涉及到的有用的办法和数据结构,这些办法和数据结构都很值得花时刻去了解:

数据透视表:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Dataframe.pivot.html?source=post_page---------------------------

时刻序列/日期功用:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html?source=post_page---------------------------;

绘图:https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html?source=post_page---------------------------。

总结

期望你能够由于这篇简略的文章,更好地了解 Pandas 背面的作业原理,以及 Pandas 库的开展现状。本文还展现了不同的用于优化数据框内存以及快速剖析数据的东西。期望对现在的你来说,索引和查找的概念能愈加明晰。最终,你还能够试着用办法链写更长的链。

这儿还有一些笔记:https://github.com/unit8co/medium-pandas-wan?source=post_page---------------------------

除了文中的一切代码外,还包含简略数据索引数据框(df)和多索引数据框(mi_df)功用的守时目标。

游刃有余,所以持续修炼技术,并协助咱们树立一个更好的国际吧。

PS:有时候纯用 Numpy 会更快。

本文为机器之心编译,转载请联络本大众号取得授权。

------------------------------------------------

“如果发现本网站发布的资讯影响到您的版权,可以联系本站!同时欢迎来本站投稿!