0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

25个Pandas实用技巧

数据分析与开发 来源:数据分析与开发 作者:数据分析与开发 2022-03-14 10:33 次阅读

从剪贴板中创建DataFrame

假设你将一些数据储存在Excel或者Google Sheet中,你又想要尽快地将他们读取至DataFrame中。你需要选择这些数据并复制至剪贴板。然后,你可以使用read_clipboard()函数将他们读取至DataFrame中:

5ea29752-9753-11ec-952b-dac502259ad0.png

和read_csv()类似,read_clipboard()会自动检测每一列的正确的数据类型:

5eb8935e-9753-11ec-952b-dac502259ad0.png

让我们再复制另外一个数据至剪贴板:

5ed0165a-9753-11ec-952b-dac502259ad0.png

神奇的是,pandas已经将第一列作为索引了:

5ee93a04-9753-11ec-952b-dac502259ad0.png

需要注意的是,如果你想要你的工作在未来可复制,那么read_clipboard()并不值得推荐

将DataFrame划分为两个随机的子集

假设你想要将一个DataFrame划分为两部分,随机地将75%的行给一个DataFrame,剩下的25%的行给另一个DataFrame。


举例来说,我们的movie ratings这个DataFrame有979行:

5efb83b2-9753-11ec-952b-dac502259ad0.png

我们可以使用sample()函数来随机选取75%的行,并将它们赋值给"movies_1"DataFrame:

5f0fdea2-9753-11ec-952b-dac502259ad0.png

接着我们使用drop()函数来舍弃“moive_1”中出现过的行,将剩下的行赋值给"movies_2"DataFrame:

5f1dea2e-9753-11ec-952b-dac502259ad0.png

你可以发现总的行数是正确的:

5f3aee58-9753-11ec-952b-dac502259ad0.png

你还可以检查每部电影的索引,或者"moives_1":

5f537180-9753-11ec-952b-dac502259ad0.png

或者"moives_2":

5f6591da-9753-11ec-952b-dac502259ad0.png

需要注意的是,这个方法在索引值不唯一的情况下不起作用。

注:该方法在机器学习或者深度学习中很有用,因为在模型训练前,我们往往需要将全部数据集按某个比例划分成训练集和测试集。该方法既简单又高效,值得学习和尝试。

多种类型过滤DataFrame

让我们先看一眼movies这个DataFrame:

In[60]: movies.head() Out[60]:

5f7f92ce-9753-11ec-952b-dac502259ad0.png

其中有一列是genre(类型):

5f9f00d2-9753-11ec-952b-dac502259ad0.png

比如我们想要对该DataFrame进行过滤,我们只想显示genre为Action或者Drama或者Western的电影,我们可以使用多个条件,以"or"符号分隔:

In[62]: movies[(movies.genre=='Action')| (movies.genre=='Drama')| (movies.genre== 'Western')].head() Out[62]:

5fae1c66-9753-11ec-952b-dac502259ad0.png

但是,你实际上可以使用isin()函数将代码写得更加清晰,将genres列表传递给该函数:

In[63]: movies[movies.genre.isin(['Action','Drama','Western'])].head() Out[63]:

5fc0b600-9753-11ec-952b-dac502259ad0.png

如果你想要进行相反的过滤,也就是你将吧刚才的三种类型的电影排除掉,那么你可以在过滤条件前加上破浪号:

In[64]: movies[~movies.genre.isin(['Action', 'Drama','Western'])].head() Out[64]:

5fdcd3b2-9753-11ec-952b-dac502259ad0.png

这种方法能够起作用是因为在Python中,波浪号表示“not”操作。

DataFrame筛选数量最多类别

假设你想要对movies这个DataFrame通过genre进行过滤,但是只需要前3个数量最多的genre。

我们对genre使用value_counts()函数,并将它保存成counts(type为Series):

5ff3f7cc-9753-11ec-952b-dac502259ad0.png

该Series的nlargest()函数能够轻松地计算出Series中前3个最大值:

600652fa-9753-11ec-952b-dac502259ad0.png

事实上我们在该Series中需要的是索引:

601a6f06-9753-11ec-952b-dac502259ad0.png

最后,我们将该索引传递给isin()函数,该函数会把它当成genre列表:

In[68]: movies[movies.genre.isin(counts.nlargest(3).index)].head() Out[68]:

603124e4-9753-11ec-952b-dac502259ad0.png

这样,在DataFrame中只剩下Drame, Comdey, Action这三种类型的电影了。

处理缺失值

让我们来看一看UFO sightings这个DataFrame:

604f00e0-9753-11ec-952b-dac502259ad0.png

你将会注意到有些值是缺失的。


为了找出每一列中有多少值是缺失的,你可以使用isna()函数,然后再使用sum():

606259b0-9753-11ec-952b-dac502259ad0.png

isna()会产生一个由True和False组成的DataFrame,sum()会将所有的True值转换为1,False转换为0并把它们加起来。

类似地,你可以通过mean()和isna()函数找出每一列中缺失值的百分比。

607d0116-9753-11ec-952b-dac502259ad0.png

如果你想要舍弃那些包含了缺失值的列,你可以使用dropna()函数:

6099d49e-9753-11ec-952b-dac502259ad0.png

或者你想要舍弃那么缺失值占比超过10%的列,你可以给dropna()设置一个阈值:

60aa4b76-9753-11ec-952b-dac502259ad0.png

len(ufo)返回总行数,我们将它乘以0.9,以告诉pandas保留那些至少90%的值不是缺失值的列。

一个字符串划分成多列

我们先创建另一个新的示例DataFrame:

60bab056-9753-11ec-952b-dac502259ad0.png

如果我们需要将“name”这一列划分为三个独立的列,用来表示first, middle, last name呢?我们将会使用str.split()函数,告诉它以空格进行分隔,并将结果扩展成一个DataFrame:

60cecbc2-9753-11ec-952b-dac502259ad0.png

这三列实际上可以通过一行代码保存至原来的DataFrame:

60e7b484-9753-11ec-952b-dac502259ad0.png

如果我们想要划分一个字符串,但是仅保留其中一个结果列呢?比如说,让我们以", "来划分location这一列:

60f8c8c8-9753-11ec-952b-dac502259ad0.png

如果我们只想保留第0列作为city name,我们仅需要选择那一列并保存至DataFrame:

611277fa-9753-11ec-952b-dac502259ad0.png

Series扩展成DataFrame

让我们创建一个新的示例DataFrame:

61276232-9753-11ec-952b-dac502259ad0.png

这里有两列,第二列包含了Python中的由整数元素组成的列表。

如果我们想要将第二列扩展成DataFrame,我们可以对那一列使用apply()函数并传递给Series constructor:

6140eb58-9753-11ec-952b-dac502259ad0.png

通过使用concat()函数,我们可以将原来的DataFrame和新的DataFrame组合起来:

61547d1c-9753-11ec-952b-dac502259ad0.png

对多个函数进行聚合

让我们来看一眼从Chipotle restaurant chain得到的orders这个DataFrame:

In[82]: orders.head(10) Out[82]:

616c10c6-9753-11ec-952b-dac502259ad0.png

每个订单(order)都有订单号(order_id),包含一行或者多行。为了找出每个订单的总价格,你可以将那个订单号的价格(item_price)加起来。比如,这里是订单号为1的总价格:

617f1252-9753-11ec-952b-dac502259ad0.png

如果你想要计算每个订单的总价格,你可以对order_id使用groupby(),再对每个group的item_price进行求和。

61940edc-9753-11ec-952b-dac502259ad0.png

但是,事实上你不可能在聚合时仅使用一个函数,比如sum()。为了对多个函数进行聚合,你可以使用agg()函数,传给它一个函数列表,比如sum()和count():

61ab086c-9753-11ec-952b-dac502259ad0.png

这将告诉我们没定订单的总价格和数量。

聚合结果与DataFrame组合

让我们再看一眼orders这个DataFrame:

In[86]: orders.head(10) Out[86]:

61c83112-9753-11ec-952b-dac502259ad0.png

如果我们想要增加新的一列,用于展示每个订单的总价格呢?回忆一下,我们通过使用sum()函数得到了总价格:

61dab968-9753-11ec-952b-dac502259ad0.png

sum()是一个聚合函数,这表明它返回输入数据的精简版本(reduced version )。


换句话说,sum()函数的输出:

61f8537e-9753-11ec-952b-dac502259ad0.png

比这个函数的输入要小:

6209a49e-9753-11ec-952b-dac502259ad0.png

解决的办法是使用transform()函数,它会执行相同的操作但是返回与输入数据相同的形状:

622b0238-9753-11ec-952b-dac502259ad0.png

我们将这个结果存储至DataFrame中新的一列:

In[91]: orders['total_price']= total_price orders.head(10) Out[91]:

62455ae8-9753-11ec-952b-dac502259ad0.png

你可以看到,每个订单的总价格在每一行中显示出来了。

这样我们就能方便地甲酸每个订单的价格占该订单的总价格的百分比:

In[92]: orders['percent_of_total']=orders.item_price/orders.total_price orders.head(10) In[92]:

626ae0ce-9753-11ec-952b-dac502259ad0.png

选取行和列的切片

让我们看一眼另一个数据集:

In[93]: titanic.head() Out[93]:

627dcec8-9753-11ec-952b-dac502259ad0.png

这就是著名的Titanic数据集,它保存了Titanic上乘客的信息以及他们是否存活。


如果你想要对这个数据集做一个数值方面的总结,你可以使用describe()函数:

629353ec-9753-11ec-952b-dac502259ad0.png

但是,这个DataFrame结果可能比你想要的信息显示得更多。

如果你想对这个结果进行过滤,只想显示“五数概括法”(five-number summary)的信息,你可以使用loc函数并传递"min"到"max"的切片:

62a1f2bc-9753-11ec-952b-dac502259ad0.png

如果你不是对所有列都感兴趣,你也可以传递列名的切片:

62b9511e-9753-11ec-952b-dac502259ad0.png

MultiIndexed Series重塑

Titanic数据集的Survived列由1和0组成,因此你可以对这一列计算总的存活率:

62d0a3dc-9753-11ec-952b-dac502259ad0.png

如果你想对某个类别,比如“Sex”,计算存活率,你可以使用groupby():

62e3d880-9753-11ec-952b-dac502259ad0.png

如果你想一次性对两个类别变量计算存活率,你可以对这些类别变量使用groupby():

62f83d34-9753-11ec-952b-dac502259ad0.png

该结果展示了由Sex和Passenger Class联合起来的存活率。它存储为一个MultiIndexed Series,也就是说它对实际数据有多个索引层级。


这使得该数据难以读取和交互,因此更为方便的是通过unstack()函数将MultiIndexed Series重塑成一个DataFrame:

63174580-9753-11ec-952b-dac502259ad0.png

该DataFrame包含了与MultiIndexed Series一样的数据,不同的是,现在你可以用熟悉的DataFrame的函数对它进行操作。

创建数据透视表

如果你经常使用上述的方法创建DataFrames,你也许会发现用pivot_table()函数更为便捷:

6331390e-9753-11ec-952b-dac502259ad0.png

想要使用数据透视表,你需要指定索引(index),列名(columns),值(values)和聚合函数(aggregation function)。


数据透视表的另一个好处是,你可以通过设置margins=True轻松地将行和列都加起来:

634ae444-9753-11ec-952b-dac502259ad0.png

这个结果既显示了总的存活率,也显示了Sex和Passenger Class的存活率。


最后,你可以创建交叉表(cross-tabulation),只需要将聚合函数由"mean"改为"count":

63600a68-9753-11ec-952b-dac502259ad0.png

这个结果展示了每一对类别变量组合后的记录总数。

连续数据转类别数据

让我们来看一下Titanic数据集中的Age那一列:

63772a54-9753-11ec-952b-dac502259ad0.png

它现在是连续性数据,但是如果我们想要将它转变成类别数据呢?

一个解决办法是对年龄范围打标签,比如"adult", "young adult", "child"。实现该功能的最好方式是使用cut()函数:

638a4300-9753-11ec-952b-dac502259ad0.png

这会对每个值打上标签。0到18岁的打上标签"child",18-25岁的打上标签"young adult",25到99岁的打上标签“adult”。

注意到,该数据类型为类别变量,该类别变量自动排好序了(有序的类别变量)。

Style a DataFrame

上一个技巧在你想要修改整个jupyter notebook中的显示会很有用。但是,一个更灵活和有用的方法是定义特定DataFrame中的格式化(style)。


让我们回到stocks这个DataFrame:

63a1621a-9753-11ec-952b-dac502259ad0.png

我们可以创建一个格式化字符串的字典,用于对每一列进行格式化。然后将其传递给DataFrame的style.format()函数:

63ca81cc-9753-11ec-952b-dac502259ad0.png

注意到,Date列是month-day-year的格式,Close列包含一个$符号,Volume列包含逗号。


我们可以通过链式调用函数来应用更多的格式化:

63dbfa2e-9753-11ec-952b-dac502259ad0.png

我们现在隐藏了索引,将Close列中的最小值高亮成红色,将Close列中的最大值高亮成浅绿色。


这里有另一个DataFrame格式化的例子:

63f42e46-9753-11ec-952b-dac502259ad0.png

Volume列现在有一个渐变的背景色,你可以轻松地识别出大的和小的数值。


最后一个例子:

641b57f0-9753-11ec-952b-dac502259ad0.png

现在,Volumn列上有一个条形图,DataFrame上有一个标题。

请注意,还有许多其他的选项你可以用来格式化DataFrame。

额外技巧

Profile a DataFrame

假设你拿到一个新的数据集,你不想要花费太多力气,只是想快速地探索下。那么你可以使用pandas-profiling这个模块。

在你的系统上安装好该模块,然后使用ProfileReport()函数,传递的参数为任何一个DataFrame。它会返回一个互动的HTML报告:

第一部分为该数据集的总览,以及该数据集可能出现的问题列表

第二部分为每一列的总结。你可以点击"toggle details"获取更多信息

第三部分显示列之间的关联热力图

第四部分为缺失值情况报告

第五部分显示该数据及的前几行

使用示例如下(只显示第一部分的报告):

642bc072-9753-11ec-952b-dac502259ad0.png

原文链接:
https://nbviewer.jupyter.org/github/justmarkham/pandas-videos/blob/master/top_25_pandas_tricks.ipynb

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4338

    浏览量

    62739
  • 机器学习
    +关注

    关注

    66

    文章

    8424

    浏览量

    132766

原文标题:这 25 个 Pandas 实用技巧你都会吗

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    实用技巧助您轻松构建适龄应用

    应用开发者在塑造各年龄段用户与技术交互方式中发挥着至关重要的作用。无论您的应用内容是专为儿童设计,还是仅仅为了吸引他们的注意力,您都有责任确保提供安全且值得信赖的体验。Google 会随时为您提供支持。在此,我们将分享一些重要的提醒和更新,介绍我们如何帮助开发者在整个 Android 生态系统中构建优质、有吸引力且适合各年龄段的应用。
    的头像 发表于 12-26 15:33 115次阅读

    将AINN和AGND接在了一起,请问AMC1306M25的AGND的地和隔离电源的地是一地吗?

    我正在评估AMC1306M25,有问题想要请教: 我做了一 隔离电源,输出5V,将5V电源供给AMC1306M25,AMC1306M25
    发表于 12-23 08:25

    易飞扬25G SFP28 ZR,突破25G传输距离

    在当今快节奏的数字时代,数据传输的稳定性和效率成为了网络应用的核心要素。易飞扬25G SFP28 ZR,一款专为长距离网络应用设计的传输模块,是 25G以太网和数据中心互连的理想选择。
    的头像 发表于 11-29 16:06 155次阅读

    RAPIDS cuDF将pandas提速近150倍

    在 NVIDIA GTC 2024 上,NVIDIA 宣布,RAPIDS cuDF 当前已能够为 950 万 pandas 用户带来 GPU 加速,且无需修改代码。
    的头像 发表于 11-20 09:52 213次阅读
    RAPIDS cuDF将<b class='flag-5'>pandas</b>提速近150倍

    意法半导体推出新电源管理芯片STPMIC25

    ‍‍‍‍‍‍‍‍优化的集成化电源管理芯片,内置保护功能,驱动MPU及外设 意法半导体STM32MP2微处理器配套电源管理芯片STPMIC25现已上市。新产品在一便捷封装内配备16输出通道,可为
    的头像 发表于 10-29 13:53 316次阅读

    英伟达股价一月内上涨25%

    统计数据显示,在过去一月中,英伟达公司的股价上涨了 25%,股价目前已经接近了历史高位,英伟达公司的市值已超越微软公司,成为市值第二高的公司。 尽管已经是处于疯涨的阶段,但是很多分析师依然非常
    的头像 发表于 10-11 15:23 453次阅读

    国产铁电存储器SF25C20可替换FM25V20A用于医疗监护仪

    国产铁电存储器SF25C20可替换FM25V20A用于医疗监护仪
    的头像 发表于 09-19 09:43 257次阅读
    国产铁电存储器SF<b class='flag-5'>25</b>C20可替换FM<b class='flag-5'>25</b>V20A用于医疗监护仪

    替代FM25V20A,国产FRAM SF25C20在整车VCU中的应用

    替代FM25V20A,国产FRAM SF25C20在整车VCU中的应用
    的头像 发表于 09-06 09:53 340次阅读
    替代FM<b class='flag-5'>25</b>V20A,国产FRAM SF<b class='flag-5'>25</b>C20在整车VCU中的应用

    keil实用技巧

    和测试工作。一、统一编程风格1、插件介绍及下载Astyle全称ArtisticStyle,是一免费,快速,小型的自动格式化程序,适用于C,C++,C++/CLI,O
    的头像 发表于 08-30 13:23 922次阅读
    keil<b class='flag-5'>实用技巧</b>

    通向数字创新之路:25组合电路核心主题概念

    组合电路是数字系统的基础构建模块。深入理解以下25主题,将有助于全面掌握组合电路的原理和应用:01.布尔代数布尔代数是数字逻辑的理论基础。它包括AND、OR、NOT和XOR等基本操作,为理解
    的头像 发表于 08-15 18:28 621次阅读
    通向数字创新之路:<b class='flag-5'>25</b><b class='flag-5'>个</b>组合电路核心主题概念

    SMJ320C25 SMJ320C25-50数字信号处理器数据表

    电子发烧友网站提供《SMJ320C25 SMJ320C25-50数字信号处理器数据表.pdf》资料免费下载
    发表于 08-02 09:22 0次下载
    SMJ320C<b class='flag-5'>25</b> SMJ320C<b class='flag-5'>25</b>-50数字信号处理器数据表

    1200V 25A沟槽和场阻IGBT JJT25N120SE数据手册

    电子发烧友网站提供《1200V 25A沟槽和场阻IGBT JJT25N120SE数据手册.pdf》资料免费下载
    发表于 04-10 16:59 0次下载

    为什么在25对的110配线架基座上安装时不用55对连接块

    25对的110配线架基座上安装时,不建议使用55对连接块,主要出于以下原因: 接触可靠性更高:使用4对连接块可以确保每个连接块之间有一定的距离,减少了连接块之间的干扰,从而提高了连接的可靠性
    的头像 发表于 03-04 12:01 388次阅读

    广达年终奖发放,最高可达25

    据了解,过去广达年奖金发放通常维持在2到5月之间,而最近两年已经提升到了2.5到6月,如今更是达到历年峰值。若再加上去年10月份发放的分红,表现优异的广达员工甚至可能获得2023年总计高达25
    的头像 发表于 02-02 15:25 1052次阅读

    DK5V45R25C东科反激SSR两引脚同步整流芯片

    产品概述DK5V45R25C是一款简单高效率的同步整流芯片,只有A,K两引脚,分别对应肖特基二极管PN管脚。芯片内部集成了45V功率NMOS管,可以大幅降低二极管导通损耗,提高整机效率,取代或替换
    的头像 发表于 01-27 16:50 691次阅读
    DK5V45R<b class='flag-5'>25</b>C东科反激SSR两<b class='flag-5'>个</b>引脚同步整流芯片