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')
工作中遇到常见问题及解决措施
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文件中,最经常出现的一个问题:
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.
以上总结了:
本文分享自 程序员郭震zhenguo 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!