乐趣区

关于python:Pandas-不擅长的结构化数据运算

Pandas 是 python 的一个数据分析包,是基于 NumPy 的一种数据分析工具,其中纳入了大量库和一些规范的数据模型,提供了疾速便捷地解决数据的函数和办法,是高效地操作结构化数据集所需的工具,也是使 Python 成为弱小而高效的数据分析环境的重要因素之一。

然而置信常常应用 Pandas 的同学在解决结构化数据运算时也会遇到一些麻烦,这些问题要么使得问题解决很简单(代码难写),要么使得运行极其迟缓(效率低下),上面总结整顿了一些 Pandas 的艰难问题进行吐槽,如有舛误欢送斧正,也欢送大家加入到这次的“Pandas 吐槽大会”。

切片赋值

切片赋值,指取数据中的某个值或某一块值,批改其中的值,如把第 3 行第 5 列的 x 值批改为 y 值。

应用员工信息数据作为案例进行介绍,数据片段如下:

问题一:将 R &D 部门员工的工资改成 20000

Python 代码

运行后果:

SettingWithCopyWarning:

A value is trying to be set on a copy of a slice from a DataFrame.

Try using .loc\[row\_indexer,col\_indexer\] = value instead

能够看到,报了这个 SettingWithCopyWarning,而且批改的值并没有起作用。置信这个问题对于大多数的 Pandas 用户并不生疏,那么怎么批改呢?

就像 SettingWithCopyWarning 中提醒的那样,应用 df.loc\[row\_indexer,col\_indexer\] = value 进行批改,这样不仅能够失去正确的后果,而且也能够解决报警的问题。

代码批改如下:

运行后果:

这才是 Pandas 解决问题的计划。

探讨:问题的本质是咱们想通过批改视图批改源数据。而 data\[data\[‘DEPT’\]==’R&D’\]\[‘SALARY’\]=2000 是将两个索引操作链接在一起,即间接应用了两次方括号的链式索引。

  1. data\[data\[‘DEPT’\]==’R&D’\]
  2. \[‘SALARY’\]=20000

以上两个链式操作一个接一个地独立执行。第一次链式操作是为了 Get,返回一个 DataFrame,其中蕴含所有 DEPT 等于 ‘R&D’ 的行;第二次链式操作是为了 Set,是在这个新返回的 DataFrame 上运行的,并没有批改原始的 DataFrame。而此时应用 loc 函数取得原 DataFrame 的视图,在视图上赋值就能够批改原始 DataFrame 的值。

这种问题还是比拟容易发现的,上面再来看一种状况:

问题二:批改 R&D 部门 5 号员工的工资为 19950

问题剖析:在理论的工作中,常常把视图赋值给某个变量进行后续的计算,直到某一步,又想批改其中的某行的值,此时再应用 loc 函数时也会呈现 SettingWithCopyWarning

Python 代码:

运行后果:

SettingWithCopyWarning:

A value is trying to be set on a copy of a slice from a DataFrame.

Try using .loc\[row\_indexer,col\_indexer\] = value instead

察看发现,即便应用了 loc 函数,当再次应用 loc 函数时,还是会呈现 SettingWithCopyWarning 的报警,其中的起因还是将两个索引操作链接在一起,第一次为 get,第二次为 set。这次所不同的是赋值后果起作用了,失去了咱们冀望的后果。但咱们也不应该疏忽此 Warning,而是应该明确的通知 Pandas 变量 r_d 是 data 中截取视图的正本,而后再应用 loc 函数批改 5 号员工的工资。

代码如下:

运行后果:

探讨:var=df.copy() 是明确的告知此 var 是 DataFrame 的正本,此时再应用 loc 函数赋值时,就防止了两次链式索引,也就防止了 SettingWithCopyWarning 的正告。

Pandas 针对 df 的操作冷不防就会产生视图,赋值时会错位,同时也会浪费时间。

汇合运算

常见的汇合运算,包含交加,差集,并集,异或集和和集运算,上面来看下 Pandas 两个汇合间的运算。

问题三:求销售部门的员工与女员工的交加,差集,并集,异或集和和集。

Python 代码:

探讨:Pandas 汇合运算时,只能对着索引进行,而后再从原始数据中按索引截取失去后果。DataFrame 不能够间接进行汇合运算。而且当汇合数多于两个时,须要通过循环两两计算失去后果,再从原始数据按索引截取。当心愿依照某列进行汇合运算时,则还须要把该列转成索引,计算实现后还要重置索引,失去后果。对于简略的汇合运算看起来就很麻烦,如果 Pandas 能反对汇合 (set) 数据类型的汇合运算,通过符号 (&-|^) 进行运算就好了。

聚合运算

Pandas 提供了很多聚合运算函数,比方求和 sum(),均匀 mean(),计数 count(),方差 var(),标准差 std() 等等。但遇到略微非凡一点聚合运算时就有点麻烦,请看以下两个问题。

问题四:查看所有工资最高的员工的信息

问题剖析:首先找到最高工资,再筛选出等于最高工资的员工。

Python 代码:

探讨:这种形式须要遍历两边数据,计算最大值时一遍,过滤时一遍,效率比拟低。有一种形式能够只遍历一遍。即找最大值的同时记录下最大值员工的索引,而后间接利用索引取数就能够了。可是 Pandas 的 idxmax() 函数只返回一个最大值的索引,不能够返回全副最大值的索引,因而就只能用上边的笨办法来解决这个问题。

问题五:找到年龄最大的 5 位员工,即 TOPN 问题。

问题剖析:最大值是相当于 TOP1,因而 TOPN 问题也相当于聚合运算。

Python 代码:

探讨:TOPN 问题并不需要大排序,只须要保护一个 N 长度的序列即可,放弃序列中的 N 个数总是遍历过的数据中的最大值或者最小值即可。大家都晓得大排序的效率是很低的,而且当数据量很大时,大排序复杂度和效率又会进一步好转。但 Pandas 并没有提供高效的计算函数。即便是 nlargest() 和 nsmallest() 函数底层也是大排序后取前五。

定位计算

Pandas 提供了索引性能,用户能够应用索引进行切片等操作,但当遇到须要计算指定索引(即地位)比前一行的行就比拟麻烦,如上面这个问题:

问题六:计算股价超过 100 的交易日的当日涨幅

问题剖析:须要筛选出股价超过 100 的交易日的交易信息,将数据提前一天,应用雷同的索引截取两份数据,计算两者的涨幅。

Python 代码:

探讨:Python 并没有提供利用地位进行相干计算的函数,所以计算这类问题就略显麻烦。

分组运算

Pandas 提供了丰盛的分组运算,既能够依照列名分组,也能够依照指定的数组分组,既能够对单列应用多种形式聚合,也能够对多列聚合,还能够循环各组,解决分组当前的汇合。但有一些常见的分组运算应用 Pandas 做起来要么比拟繁琐,要么效率低下。

比方按地位分组、值变动分组、条件变动分组都须要衍生出一个数组作为分组根据,对位分组则须要应用 left join 的形式来绕,枚举分组更是须要屡次分组,筛选须要的分组再合并,这里有一篇文章具体介绍了 Pandas 分组运算的一些例子

Python 分组解决

大家能够通过具体的例子领会 Pandas 分组的不便之处。

并行运算

Pandas 并不提供并行计算的办法,这也是 Pandas 被诟病最多的一方面,而 Python 所谓的多线程对于 CPU 而言还是单线程。

大数据计算

Pandas 尽管能够应用分段读取的形式来获取数据,但想要实现一些简单的运算,比方排序、分组、关联等等都会十分十分麻烦,而且对程序员的技术要求也会很高。具体阐述能够查看另一篇文档。

Python 如何解决大文件

退出移动版