Pandas是python的数据分析包,基于NumPy的数据分析工具,融合了大量库和一些标准数据模型,提供了一种快速便捷的数据处理方式函数和方法是高效操作结构化数据集所需的工具,是使Python成为强大高效的数据分析环境的重要因素之一。不过相信经常使用Pandas的同学在处理结构化数据操作的时候也会遇到一些麻烦。这些问题要么使问题求解变得非常复杂(难以编写代码),要么使操作变得极其缓慢(效率低下)。以下总结了一些,如有错误,欢迎指正,欢迎大家参与本次“熊猫吐槽大会”。切片赋值切片赋值是指取数据中的某个值或一组值,并对值进行修改,比如将第3行第5列的x值修改为y值。以员工信息数据为例进行介绍,数据片段如下:问题一:将研发部员工的工资改为20000Python代码运行结果:SettingWithCopyWarning:AvalueistryingtobesetonacopyofaslicefromaDataFrame.Tryusing.loc\[row\_indexer,col\_indexer\]=valueinstead可以看到报了这个SettingWithCopyWarning,修改后的值不起作用。相信大多数Pandas用户都熟悉这个问题,那么如何解决呢?SettingWithCopyWarning中建议,使用df.loc\[row\_indexer,col\_indexer\]=value进行修改,这样既可以得到正确的结果,又可以解决warning问题。代码修改如下:运行结果:这是Pandas对问题的解决方案。讨论:问题的本质是我们想通过修改视图来修改源数据。而data\[data\['DEPT'\]=='R&D'\]\['SALARY'\]=2000就是把两个索引操作连在一起,也就是直接用两次方括号的链式索引。data\[data\['DEPT'\]=='R&D'\]\['SALARY'\]=20000以上两个链式操作依次独立执行。第一个链操作是针对Get的,它返回一个DataFrame,其中包含DEPT等于'R&D'的所有行;第二个链式操作是针对Set的,操作的是这个新返回的DataFrame,并没有修改原来的DataFrame。此时使用loc函数获取原始DataFrame的视图,并在视图上赋值,修改原始DataFrame的值。这种问题比较好找,再来看另一种情况:问题2:将研发部5号员工的工资修改为19950问题分析:在实际工作中,往往会将视图赋值给一个变量,用于后续计算,到某一步,想修改某一行的值,再用loc函数也会出现SettingWithCopyWarningPython代码:运行结果:SettingWithCopyWarning:AvalueistryingtobesetonacopyofaslicefromaDataFrame.Tryusing.loc\[row\_indexer,col\_indexer\]=valueinstead观察到即使使用了loc函数,再次使用loc函数时,仍然会出现SettingWithCopyWarning的告警。原因是两个索引操作Chained在一起,第一次是get,第二次是set。这次的不同之处在于作业有效,我们得到了想要的结果。但是我们不应该忽视这个警告。相反,我们应该显式地告诉Pandas变量r_d是data中截取视图的副本,然后使用loc函数修改5号员工的工资。代码如下:运行结果:讨论:var=df.copy()是明确告知这个var是DataFrame的拷贝。此时使用loc函数赋值时,避免了两个链索引,也避免了SettingWithCopyWarning。警告。pandas对df的操作会意外的产生视图,赋值的时候会错位,也会浪费时间。集合运算常见的集合运算有交、差、并、异或、和。让我们看看Pandas中两个集合之间的操作。问题3:求销售部员工与女员工的交、差、并、异或、和。Python代码:讨论:Pandas的集合操作只能针对索引进行,然后根据索引从原始数据中得到结果。DataFrame不能直接进行集合操作。而当集合数量超过2个时,就需要逐对循环计算结果,然后根据索引从原始数据中截取。当你想根据某一列进行集合操作时,需要将列转化为索引,计算完成后重新设置索引得到结果。对于简单的集合操作,显得繁琐。如果Pandas可以支持集合数据类型的集合操作,用符号(&-|^)来进行操作就好了。聚合操作Pandas提供了很多聚合操作函数,如sumsum()、averagemean()、countcount()、variancevar()、standarddeviationstd()等。但是遇到稍微特殊的聚合操作就有点麻烦了,请看下面两个问题。问题四:查看所有薪水最高的员工信息问题分析:先找到薪水最高的,然后筛选出与薪水相等的员工。Python代码:讨论:该方法需要遍历两边的数据,计算最大值时遍历一次,过滤时遍历一次,效率比较低。有一种方法可以只做一次。即在求最大值的同时,记录最大值员工的索引,然后直接用索引取号。但是pandas的idxmax()函数只返回一个最大值的索引,并不能返回所有最大值的索引,所以只能用上面的笨方法来解决这个问题。问题五:找出年龄最大的5名员工,TOPN问题。问题分析:最大值相当于TOP1,所以TOPN问题也相当于聚合操作。Python代码:讨论:TOPN问题不需要大排序,只需要维护一个N长的序列,并保持序列中的N个数始终为遍历数据中的最大值或最小值即可。大家都知道大排序的效率是很低的,当数据量很大的时候,大排序的复杂度和效率会进一步变差。但是Pandas并没有提供高效的计算功能。就连最底层的nlargest()和nsmallest()函数也是在大排序后取前五。位置计算Pandas提供了索引功能,用户可以使用索引进行切片等操作,但是计算指定索引(即位置)比上一行要麻烦一些,比如下面的问题:问题6:计算股价超过100交易日日涨幅分析:需要过滤掉股价超过100的交易日的交易信息,将数据提前一天,用同一个指标截取两个数据,并计算两者的增幅。Python代码:讨论:Python没有提供使用位置进行相对计算的函数,所以计算这类问题有点麻烦。分组操作Pandas提供了丰富的分组操作,可以按列名分组,也可以按指定数组分组。它可以针对单个列以多种方式聚合,也可以针对多个列进行聚合。它还可以循环遍历每个组来处理分组。后来的收藏。但是有一些常见的分组操作对Pandas来说要么麻烦要么效率低下。比如按位置分组,按值变化分组,按条件变化分组,都需要导出一个数组作为分组的依据。对齐分组需要使用leftjoin的方式环绕。枚举分组需要多次分组。合并,这里有一篇文章详细介绍了一些Pandas分组操作的例子Python分组处理大家可以通过具体的例子来体会Pandas分组的不便之处。并行计算Pandas没有提供并行计算的方法,这是Pandas最受诟病的地方,而Python所谓的多线程对于CPU来说还是单线程的。大数据计算虽然Pandas可以使用分段读取来获取数据,但是实现一些复杂的操作会非常非常麻烦,比如排序、分组、关联等,对程序员的技术要求也会很高。.详细讨论见另一篇文档。Python如何处理大文件
