当前位置: 首页 > backend >正文

【数据分析】第四章 pandas简介(2)

4.5 索引对象的其他功能

与 Python 常用数据结构相比,pandas 不仅利用了 NumPy 数组的高性能优势,还巧妙地整合了索引机制。

最终事实证明,这样做颇有几分成效。事实上,虽然已有的动态数据结构极为灵活,但在结构中增加诸如标签这样的内部索引机制,为接下来及下一章要讲解的一系列必要操作,提供了更为简单、直接的执行方法。

这一节,我们来详细分析几种使用索引机制实现的基础操作:

  • 更换索引

  • 删除

  • 数据对齐

4.5.1 更换索引

前面我们讲过,数据结构一旦声明,Index 对象就不能改变。这么说一点也没错,但是执行更换索引操作就可以“解决”这个问题。

事实上,重新定义索引之后,我们就能够用现有的数据结构生成一个新的数据结构。

>>> ser = pd.Series([2, 5, 7, 4], index=['one', 'two', 'three', 'four'])
>>> ser
one      2
two      5
three    7
four     4
dtype: int64

pandas 的 reindex() 函数可以更换 Series 对象的索引。它根据新的标签序列,重新调整原 Series 的元素,生成一个新的 Series 对象。

更换索引时,你可以调整索引序列中各标签的顺序,删除或增加新标签。如果增加新标签,pandas 会添加 NaN 作为其元素。

>>> ser.reindex(['three', 'four', 'five', 'one'])
three    7.0
four     4.0
five     NaN
one      2.0
dtype: float64

从返回结果可以看到,标签顺序全部调整过。删除了标签 two 及其元素,增加了新标签 five,而 five 由于没有对应的值,被填充为 NaN。请注意,当出现 NaN 值时,dtype 会自动提升为 float64

然而,重新编制索引时,定义所有的标签序列可能会很麻烦,对大型 DataFrame 来说更是如此。但是我们可以使用自动填充或插值方法。

为了更好地理解自动编制索引功能,我们先来定义以下 Series 对象。

>>> ser3 = pd.Series([1, 5, 6, 3], index=[0, 3, 5, 6])
>>> ser3
0    1
3    5
5    6
6    3
dtype: int64

刚定义的 Series 对象,其索引列并不完整,而是缺失了几个值(例如1、2和4)。常见的需求是通过插值得到一个完整的序列。方法是使用 reindex() 函数,并将 method 选项的值设置为 'ffill'(forward fill,向前填充)。此外,还需要指定索引值的范围。要指定一个0到5的值的完整序列,参数可以设置为 range(6)

>>> ser3.reindex(range(6), method='ffill')
0    1
1    1
2    1
3    5
4    5
5    6
dtype: int64

由结果可见,新 Series 对象添加了原 Series 对象缺失的索引项。新插入的索引项,其元素为前面索引编号比它小的那一项的元素。所以我们看到索引项1、2的值为1,也就是索引项0的值。

如果你想用新插入索引后面的元素来填充缺失值,需要使用 'bfill' 方法(backward fill,向后填充)。

>>> ser3.reindex(range(6), method='bfill')
0    1
1    5
2    5
3    5
4    6
5    6
dtype: int64

用这种方法,索引项1和2的元素则为5,也就是索引项3的元素。

更换索引的概念可以由 Series 扩展到 DataFrame,你不仅可以更换行索引,还可以更换列,甚至同时更换两者。如前所述,我们可以增加行或列,但 pandas 会用 NaN 弥补原数据结构中缺失的元素。

让我们首先重新创建 frame 对象,因为它在前面的操作中可能被修改过:

>>> data = {'color': ['blue', 'green', 'yellow', 'red', 'white'],
...         'object': ['ball', 'pen', 'pencil', 'paper', 'mug'],
...         'price': [1.2, 1.0, 0.6, 0.9, 1.7]}
>>> frame = pd.DataFrame(data)
>>> framecolor  object  price
0    blue    ball    1.2
1   green     pen    1.0
2  yellow  pencil    0.6
3     red   paper    0.9
4   white     mug    1.7

现在,我们尝试对 frame 进行 reindex 操作。这里,我们尝试重新索引行(使用 range(5))并重新指定列(columns=['color', 'price', 'new', 'object'])。

>>> frame.reindex(range(5), method='ffill', columns=['color', 'price', 'new', 'object'])color  price  new  object
0    blue    1.2  NaN    ball
1   green    1.0  NaN     pen
2  yellow    0.6  NaN  pencil
3     red    0.9  NaN   paper
4   white    1.7  NaN     mug
4.5.2 删除

另一种与 Index 对象相关的操作是删除。因为索引和列名称都有了标签作为标识,所以删除操作变得非常简单。

pandas 专门提供了一个用于删除操作的函数:drop(),它返回不包含已删除索引及其元素的新对象。

举例来说,我们想从 Series 对象中删除一项。为此,我们先来定义一个含有四个元素的 Series 对象,其中各元素标签均不相同。

>>> ser = pd.Series(np.arange(4.), index=['red', 'blue', 'yellow', 'white'])
>>> ser
red       0.0
blue      1.0
yellow    2.0
white     3.0
dtype: float64

假如我们想删除标签为 yellow 的这一项。用标签作为 drop() 函数的参数,就可以删除这一项。

>>> ser.drop('yellow')
red     0.0
blue    1.0
white   3.0
dtype: float64

传入一个由多个标签组成的列表,可以删除多项。

>>> ser.drop(['blue', 'white'])
red       0.0
yellow    2.0
dtype: float64

要删除 DataFrame 中的元素,需要指定元素所在的轴标签。我们通过具体的例子来看一下,首先声明一个 DataFrame 对象。

>>> frame = pd.DataFrame(np.arange(16).reshape((4,4)),
...                        index=['red', 'blue', 'yellow', 'white'],
...                        columns=['ball', 'pen', 'pencil', 'paper'])
>>> frameball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15

传入行的索引列表可删除行。

>>> frame.drop(['blue', 'yellow'])ball  pen  pencil  paper
red       0    1       2      3
white    12   13      14     15

要删除列,你需要指定列的标签,但是还必须用 axis 选项指定从哪个轴删除元素。如按照列的方向删除,axis 的值为 1(或者 'columns')。

>>> frame.drop(['pen', 'pencil'], axis=1)ball  paper
red        0      3
blue       4      7
yellow     8     11
white     12     15
4.5.3 算术和数据对齐

pandas 能够将两个数据结构的索引对齐,这可能是与 pandas 数据结构索引对象有关的最强大的功能。这一点尤其体现在数据结构之间的算术运算上。参与运算的两个数据结构,其索引项顺序可能不一致,而且有的索引项可能只存在于一个数据结构中。

从下面几个例子中,你就会发现做算术运算时,pandas 很擅长对齐不同数据结构的索引项。我们来举个例子,先来定义两个 Series 对象,分别指定两个不完全一致的标签数组。

>>> S1 = pd.Series([3, 2, 5, 1], ['white', 'yellow', 'green', 'blue'])
>>> S2 = pd.Series([1, 4, 7, 2, 1], ['white', 'yellow', 'black', 'blue', 'brown'])

算术运算种类很多,我们考虑一下最简单的求和运算。刚定义的两个 Series 对象,有些标签两者都有,有些只属于其中一个对象。如果一个标签,两个 Series 对象都有,就把它们的元素相加。反之,标签也会显示在结果(新 Series 对象)中,只不过元素为 NaN

>>
http://www.xdnf.cn/news/10789.html

相关文章:

  • AI与区块链:数据确权与模型共享的未来
  • recipes中声明 DEPENDS += “virtual/kernel“ 的效果
  • 『uniapp』把接口的内容下载为txt本地保存 / 读取本地保存的txt文件内容(详细图文注释)
  • Qt开发:QThreadPool的介绍和使用
  • 如何合理设计缓存 Key的命名规范,以避免在共享 Redis 或跨服务场景下的冲突?
  • 【QT】在Qt6的`QTextEdit`中,同一行更新内容
  • 浅谈边缘计算
  • K8s基础一
  • QUIC——UDP实现可靠性传输
  • 数据结构:递归的种类(Types of Recursion)
  • 云计算 Linux Rocky day03
  • 电子电路:什么是晶振?
  • Java项目OOM排查
  • 云原生架构下的现代化应用治理:理念、挑战与实践路径
  • CSS 表单设计与实现技巧
  • Apache Iceberg 如何实现分布式 ACID 事务:深度解析大数据时代的可靠数据管理
  • Spring @Value注解的依赖注入实现原理
  • Unity——QFramework工具 AciontKit时序动作执行系统
  • React 第五十一节 Router中useOutletContext的使用详解及注意事项
  • Lua和JS的垃圾回收机制
  • Fuse.js:打造极致模糊搜索体验
  • 网络安全-等级保护(等保) 3-3 GB/T 36627-2018 《信息安全技术 网络安全等级保护测试评估技术指南》-2018-09-17发布【现行】
  • 湖北理元理律师事务所:系统性债务化解中的法律技术革新
  • 0518蚂蚁暑期实习上机考试题1:数组操作
  • 实现仿中国婚博会微信小程序
  • Redis缓存-数据淘汰策略
  • 工作服/反光衣检测算法AI智能分析网关V4安全作业风险预警方案:筑牢矿山/工地/工厂等多场景安全防线
  • Java基础之数组(附带Comparator)
  • Deepseek/cherry studio中的Latex公式复制到word中
  • 云原生时代 Kafka 深度实践:06原理剖析与源码解读