前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >玩转Pandas,让数据处理更easy系列3

玩转Pandas,让数据处理更easy系列3

作者头像
double
发布2018-07-25 18:08:48
1.4K0
发布2018-07-25 18:08:48
举报
文章被收录于专栏:算法channel算法channel

01

回顾

前面介绍了Pandas最重要的两个类:Series和DataFrame,讲述了这两种数据结构常用的属性和操作,比如values,index, columns,索引,Series的增删改查,DataFrame的增删改查,Series实例填充到Pandas中,请参考:

玩转Pandas,让数据处理更easy系列1

玩转Pandas,让数据处理更easy系列2

02

读入DataFrame实例

读入的方式有很多种,可以是网络 html 爬虫到数据,可以从excel, csv文件读入的,可以是Json的数据,可以从sql库中读入,pandas提供了很方便的读入这些文件的API,以读入excel,csv文件为例:

#读入excel文件 pd.read_excel('filename', Sheet='Sheet1', encoding='utf-8') #读入csv文件 pd.read_csv('filename', encoding='utf-8')

工作中遇到常见问题及解决措施

  1. 读入提示编码问题。此时首先想到读入文件的编码格式,打开excel文件,选择编码为utf-8
  2. 读入的第一个参数可以是相对路径,此时直接为文件名,可以是绝对路径。
  3. read_excel是静态方法,不是实例方法,所以pd模块可以直接引用。

03

DataFrame实例写入到excel和csv文件中

处理读取,当然还有写入,写入API也很简单,准备好了要写入的DataFrame实例后,

#写入excel文件 pd_data.to_excel('test.xls') #读入csv文件 pd_data.to_csv('test.csv')

构造一个pd_data, 然后写入到excel文件中,

pd_data = pd.DataFrame([[1,2,3],[6,5,4]],columns=list('ABC')) pd_data.to_excel('pd_data_save.xls')

保存后的文件显示如下:

保存到excel或csv文件中,最经常出现的一个问题:

  1. 某些中文字符出现乱码。解决措施,to_csv方法的参数:encoding 设置为'utf_8_sig'. 这种方法应该是比较简洁的解决办法。

04

DataFrame遍历Series

读入或内存创建一个DataFrame实例:pd_data后,我们想根据某些条件,按照某个规则,对这些数据进行聚类,那么,一种比较直接的办法便是对pd_data遍历:

for index, seri in pd_data.iterrows(): print('index = %d' %(index)) # index: 行标签 print(seri) # seri : Series实例

输出结果如下,seri是一个Series实例

分享一个面试题,记得当年我面试时,二面的面试官直接问题pd_data.iterrows()返回的对象是什么类型,不知道大家能说的上来吗。用print(type( pd_data.iterrows() ))看下,返回结果 :generator. 中文名字叫发生器,这是个什么东东? 它是list吗?我们回顾下发生器的相关知识。

我们大家都熟悉列表,那么创建一个列表有什么问题呢?内存数量总是有限的,列表容量肯定不能超过内存大小。如果创建一个包含100万个元素的列表,不仅占用很大的存储空间,并且假如我们仅仅需要访问前面10%的元素,那后面绝大多数元素占用的空间都白白浪费了。

如果列表元素中的元素可以按照某种算法推算出来,那是否可以在循环过程中,推算出我们需要的一定数量的元素呢?这样地话,我们就可以灵活地创建需要数量的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。最难理解的就是generator和普通函数的执行流程不一样,函数是顺序执行,遇到return语句或者最后一行函数语句就返回。变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

更详细介绍可以参考:

Python|生成器

05

操作两个DataFrame实例

以上阐述了DataFrame的最基本的操作,接下来,说一个好玩的功能。如果我已知一系列点的坐标,想求出任意两点坐标之间的所有组合。该怎么使用merge接口实现这个功能。

#已知4个点的x,y坐标 s=pd.DataFrame([[1,2.0, 3.0],[2,3.2,1.4],[3,9.0,0.7],[4,3.1,2.9]], columns=['no','x','y']) s

如何用merge求出任意两点间的所有组合呢? 结果集的个数应该为4*4=16行的矩阵,具体的实现脚本为:

s1 = s.copy() #复制一份出来 s1.columns = ['s_no', 's_x', 's_y'] #修改列的标签 s2 = s.copy() s2.columns = ['e_no', 'e_x', 'e_y'] s1.loc[:,'key'] = -1 #添加一个内连接用的标签 s2.loc[:,'key'] = -1 res = s1.merge(s2,left_on='key',right_on='key') #merge默认how=inner内连接方式 res

这样就求得了任意两点之间的所有组合了,接下来,去掉添加的标签key,以及消除s_no和e_no重复的行。

06

数据过滤

利用掩码过滤数据是比较常用的,且简洁高效的方法。实现以上过滤,我们可以使用这个技术。

首先,去掉标签key这列,

res = res.drop('key',axis=1) #去掉标签为key的列

先得到掩码,条件为如下,返回的结果为一个Series实例,数据的类型为bool.

mask = res.loc[:,'s_no']!=res.loc[:,'e_no'] mask

接下来,使用如何拿这个Series实例得到最终的矩阵呢? 直接使用

res = res[ mask ] # 或 res = res.loc[mask] 都可以

为什么 loc[Series] 也可以呢? 再看下loc的API文档,可以看出bool数组也是可以的,我们又知道Series是数组和标签字典的组合。

Series.loc Purely label-location based indexer for selection by label. .loc[] is primarily label based, but may also be used with a boolean array.

去重后的结果如下:

大家一看,怎么最后一行的标签还是14啊,但是明显行数少了啊, 原来行标签断开了,这不是我们想要的,还是要从0开始连续排序啊。怎么办?

07

重置索引

DataFrame和Series实例都有reset_index方法,这是与索引相关的方法,具体实施如下:

res = res.reset_index(drop=True) res

看下参数drop的含义:

DataFrame.drop : boolean, default False Do not try to insert index into dataframe columns.This resets the index to the default integer index.

以上总结了:

  1. DataFrame的读写操作
  2. pd.iterrows返回的类型及生成器的原理
  3. DataFrame的两个实例间的操作
  4. 一个实战例子,应用了merge,掩码去重,reset_index等.
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员郭震zhenguo 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档