这一系列的对应代码,大家可以在我共享的colab上把玩,
? https://colab.research.google.com/drive/1WhKCNkx6VnX1TS8uarTICIK2ViPzNDjw
或者老规矩,订阅号后台回复 "pd" 获取
点击下面搜索框解锁小破号更多干货吧!
Pandas连续剧又来啦,在我们之前两篇文章中,
- 超详细整理!Pandas实用手册(PART I)
- 这些pandas技巧你还不会吗 | Pandas实用手册(PART II)
介绍了建立DataFrame、定制化DataFrame显示设定、数据清理&整理、获取关键数据四大类技巧,今天继续为大家带来三大类实用操作:
- 基本数据处理与转换
- 简单汇总&分析数据
- 与pandas相得益彰的实用工具
基本数据处理与转换
在了解如何选取想要的数据以后,你可以通过这节的介绍来熟悉pandas 里一些常见的数据处理方式。这章节也是我认为使用pandas 处理数据时最令人愉快的部分之一
对某一轴套用相同运算
你时常会需要对DataFrame 里头的每一个栏位(纵轴)或是每一行(横轴)做相同的运算,比方说你想将Titanic数据集内的Survived
数值栏位转换成人类容易理解的字符串:
通过apply
函数,我们把一个匿名函数lambda
套用到整个df.SurvivedSeries
之上,并以此建立一个新的存活
栏位。
值得一提的是当你需要追加新的栏位但又不想影响到原始DataFrame时,可以使用copy
函数复制一份副本另行操作。
对每一个样本做自定义运算
上小节我们用apply
函数对DataFrame里头的某个Series做运算并生成新栏位:
df[new_col] = df.Survived.apply(...
不过你时常会想要把样本(row)里头的多个栏位一次取出做运算并产生一个新的值,这时你可以自定义一个Python function并将apply
函数套用到整个DataFrame之上:
此例中apply
函数将generate_desc
函数套用到DataFrame里头的每一个样本(row),结合Sex
及Age
两栏信息,生成新的描述。
当然,将axis
设置为0则可以对每一个栏位分别套用自定义的Python function
。
将连续数值转换成分类数据
有时你会想把一个连续数值(numerical)的栏位分成多个groups以方便对每个groups做统计,这时候你可以使用pd.cut
函数:
如上所示,使用pd.cut
函数建立出来的每个分类族群 X有大小之分,因此你可以轻易地使用sort_values
函数排序样本。
将DataFrame随机切成两个子集
有时你会想将手上的DataFrame 随机切成两个独立的子集,选取其中一个子集来训练机器学习模型是一个常见的情境。
要做到这件事情有很多种方法,你可以使用scikit-learn
的train_test_split
或是numpy
的np.random.randn
,但假如你想要纯pandas解法,可以使用sample
函数:
这个解法的前提是原来的DataFrame df_titanic
里头的索引是独一无二的,另外记得设定random_state
以方便别人重现你的结果。
用SQL的方式合并两个DataFrames
很多时候你会想要将两个DataFrames 依照某个共通的栏位(键值)合并成单一DataFrame 以整合资讯,比方说给定以下两个DataFrames:
DataFrame df_city
包含了几个美国城市以及其对应的州名(state);DataFrame df_info
则包含城市名称以及一些数据。如果你想将这两个DataFrames合并(merge),可以使用非常方便的merge
函数:
没错,merge
函数运作方式就像SQL一样,可以让你通过更改how
参数来做:
left
:left outer joinright
:right outer joinouter
: full outer joininner
:inner join
注意合并后的DataFrame的最后一列:因为是left join
,就算右侧的df_info
里头并没有纽约市的资讯,我们也能把该城市保留在merge
后的结果。你还可以透过indicator=True
的方式让pandas帮我们新增一个_merge
栏位,轻松了解纽约市只存在左侧的df_city
里。merge
函数强大之处在于能跟SQL一样为我们抽象化如何合并两个DataFrames的运算。
存取并操作每一个样本
我们前面看过,虽然一般可以直接使用apply
函数来对每个样本作运算,有时候你就是会想用for
循环的方式把每个样本取出处理。
这种时候你可以用itertuples
函数:
顾名思义,itertuples
函数回传的是Python namedtuple,也是一个你应该已经很熟悉的数据类型:
简单汇总&分析数据
在对数据做些基本处理以后,你会想要从手上的DataFrame 汇总或整理出一些有用的统计数据。本节介绍一些常用的数据汇总技巧。
取出某栏位top k的值
这你在选取某栏位为top-k值的样本
小节应该就看过了。但因为这个使用情境实在太常出现,让我们再次尝试将Titanic数据集里头Ticket
栏位最常出现的值取出:
value_counts
函数预设就会把栏位里头的值依照出现频率由高到低排序,因此搭配head
函数就可以把最常出现的top k
值选出。
一行描述数值栏位
当你想要快速了解DataFrame里所有数值栏位的统计数据(最小值、最大值、平均和中位数等)时可以使用describe
函数:
你也可以用取得想要关注的数据
一节的技巧来选取自己关心的统计数据:
找出栏位里所有出现过的值
针对特定栏位使用unique
函数即可:
分组汇总结果
很多时候你会想要把DataFrame里头的样本依照某些特性分门别类,并依此汇总各组(group)的统计数据。这种时候你可以用groupby
函数。让我们再次拿出Titanic数据集:
你可以将所有乘客(列)依照它们的Pclass
栏位值分组,并计算每组里头乘客们的平均年龄:
你也可以搭配刚刚看过的describe
函数来汇总各组的统计数据:
你也可以依照多个栏位分组,并利用size
函数迅速地取得各组包含的样本数:
你也可以用agg
函数(aggregate,汇总)搭配groupby
函数来将每一组样本依照多种方式汇总:
通过unstack
函数能让你产生跟pivot_table
函数相同的结果:
当然,你也可以直接使用pivot_table
函数来汇总各组数据:
依照背景不同,每个人会有偏好的pandas 使用方式。选择对你来说最只管又好记的方式吧!
结合原始数据与汇总结果
不管是上节的groupby
搭配agg
还是pivot_table
,汇总结果都会以另外一个全新的DataFrame表示。有时候你会想直接把各组汇总的结果放到原本的DataFrame里头,方便比较原始样本与汇总结果的差异。这时你可以使用transform
函数:
此例将所有乘客依照性别Sex
分组之后,计算各组的平均年龄Age
,并利用transform
函数将各组结果插入对应的乘客(行)里头。你会发现两名男乘客跟平均男性寿命Avg_age
栏位相比正好一上一下,这差异则反映到Above_avg_age
栏位里头。
对时间数据做汇总
给定一个跟时间相关的DataFrame:
你可以用resample
函数来一招不同时间粒度汇总这个时间DataFrame:
此例中将不同年份(Year)的样本分组,并从每一组的栏位A中选出最大值,你可以查看官方resampling
说明文件来了解还有什么时间粒度可以选择(分钟、小时、月份等等)。
另外小细节是你可以利用numpy
的broadcasting
运算轻松地将DataFrame里的所有数值做操作(初始df_date
时用到的*10
)
简易绘图并修改预设样式
在Python世界里有很多数据可视化工具供你选择,比方说经典的 Matplotlib
、Seaborn
。但有时,你只需要pandas
内建的plot
函数就能轻松地将一个DataFrame转成统计图:
我们都是视觉动物,pandas
的plot
函数让你在进行探索性数据分析(Exploratory Data Analysis, EDA)
、师徒快速了解手上数据集时十分方便。
另外pandas
底层预设使用 Matplotlib 绘图,而用过 Matplotlib 的人都知道其初始的绘图样式是在不太优美,你可以通过plt.style.available
查看所有可供使用的绘图样式(style),并将喜欢的样式通过plt.style.use()
套用到所有DataFrame的plot
函数:
与pandas相得益彰的实用工具
前面几个章节介绍了不少pandas的使用技巧与操作概念,这节则介绍一些我认为十分适合与pandas一起搭配使用的数据工具/函数库。在说明每个工具的功能时,我都会使用你已经十分实习的Titanic数据集作为范例DataFrame:
tqdm:了解你的程序进度
tqdm
是一个十分强大的python进度条工具,且有整合pandas,此工具可以帮助我们了解DataFrame中apply
函数的进度。回想一下我们在之前运用过的apply
运算:
在这不到1000笔的dataframe做这样的简单运算不用一秒钟,但实际上你可能常常需要对几十万、几百万笔数据分别做复杂的运算,这时了解执行进度就是一件非常重要的事情。首先安装tqdm
:
!pip install tqdm
在这里插入图片描述
通过使用progress_apply
函数,我们可以得到跟使用apply
函数一样的结果,附赠进度条相信我,在你appy
函数很复杂且样本数很大时,你会很感谢有进度条的存在,你可以查看tqdm repo了解更多使用案例。
swifter:加速你的数据处理
swifter
函数库能以最有效率的方式执行apply
函数,同样先进行安装:
!pip install swifter
接着让我建立一个有100万样本的dataframe,测试swift
与原版apply
函数的效果差异:
在这个简单的平方运算中,swifter
版的appy
函数在colab上的效率是原始apply
函数的75倍,而要使用swifter
你也只需要加上swifter
关键字即可,何乐而不为呢?
结语
呼!本系列的pandas 旅程到此告一段落啦!
我想在其他地方你应该是找不到跟本文一样啰哩八唆的pandas 教学文章了。文章虽长,但涵盖的都是我认为十分实用的pandas 使用技巧,希望你有从中学到些东西,并开始自己的数据处理与分析之旅。如果你之后想要复习,可以公众号后台回复"pd"获取完整资料,测试自己还记得多少技巧。
接下来最重要的是培养你自己的「pandas 肌肉记忆」:「重复应用你在本文学到的东西,分析自己感兴趣的任何数据并消化这些知识」。
如果你有任何其他pandas 技巧,也请不吝留言与我分享!我懂的技巧不多,而现在轮到你教我了!
- END -