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 进行修改,这样不仅可以得到正确的结果,而且也可以解决报警的问题。

代码修改如下:

//修改赋值

import pandas as   pd

data =   pd.read_csv('Employees.csv')

data.loc[data['DEPT']=='R&D','SALARY']=20000

print(data)

运行结果:

这才是 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 如何处理大文件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容