type
status
date
slug
summary
tags
category
icon
password

引言

当涉足数据分析世界,无论是初学者还是经验丰富的分析师,都会发现Python是一个强大而灵活的工具。而在Python的数据分析生态系统中,NumPy(Numerical Python)是一个不可或缺的库,它提供了广泛的数学和统计函数,以及多维数组操作的能力。
在本博客中,将探讨NumPy库的核心功能,从创建和操作多维数组,到使用广播机制进行数组计算,再到了解结构化数组和矩阵计算。NumPy不仅提供了强大的数学工具,还是数据分析、机器学习和科学计算的基础。
无论你是希望提高数据分析技能,还是需要深入了解NumPy的各种用途,这篇博客都将为你提供宝贵的知识。让我们一起开始探索NumPy,掌握这个强大的数据分析工具!

结构体系

基于 NumPy 的知识体系梳理:
一、NumPy 基础
  1. 数组创建与操作:ndarray对象、数组切片、数组形状修改、数组数据类型、数组转换与复制
  1. 数组索引与切片:一维、二维和多维数组的索引与切片操作。
  1. 数组运算与广播:NumPy 数组支持元素级别的运算,也可以使用数学函数和线性代数函数对数组进行操作。
  1. 数组统计与排序:计算数组的最大值、最小值、平均数、中位数、方差、标准差等统计量;以及对数组进行排序。
  1. 随机数生成:使用 NumPy 可以生成各种类型的随机数,例如服从正态分布、均匀分布等的随机数。
二、NumPy 进阶
  1. 数组高级操作:布尔索引、花式索引、where 函数、迭代器等。
  1. 数组合并和拆分:vstack、hstack、concatenate 等函数可以将多个数组合并成一个数组,split、hsplit 和 vsplit 函数则可以将一个数组拆分成多个部分。
  1. 广义表与轴:广义表是由嵌套列表或数组组成的数据结构,可以用来表示树状、分层结构的数据。轴是表示数组维度的对象,通过指定轴可以对数组进行各种操作。
  1. 数组的内存布局:了解 NumPy 数组内存布局对于数组的性能优化非常重要,包括数组的 C 风格和 Fortran 风格的存储方式,以及如何使用 strides 属性来自定义数组内存布局。
  1. 结构化数组:结构化数组可以看作是表格或数据库中的行,每个元素包含多个字段,可以使用字段名或下标访问。
  1. 矩阵计算:NumPy 提供了专门的矩阵类 matrix,以及针对矩阵的一些特定运算函数,例如矩阵乘法、求逆矩阵等。

1.数组创建与操作

1.1 ndarray对象

ndarray(N-dimensional array)是NumPy中的核心数据结构,用于表示多维数组。它提供了高效的数值计算和广泛的数学函数支持。

创建ndarray对象

在NumPy中,使用np.array()函数来创建ndarray对象。例如,创建一个简单的一维数组:

数组的属性

ndarray对象有一些重要的属性:
  • 形状(shape):数组的维度和大小。
  • 数据类型(dtype):数组中元素的数据类型。
  • 维度(ndim):数组的维度数量。
  • 大小(size):数组中元素的总数。

多维数组

除了一维数组,NumPy还支持多维数组的创建。例如,创建一个二维数组:

数组索引与切片

你可以使用索引和切片来访问数组中的元素。例如,访问一维数组的第三个元素:
或者访问二维数组的特定元素:

1.2 数组切片

切片一维数组

在一维数组中,使用切片来获取数组的子集。例如,创建一个包含一些整数的一维数组:
这将输出 [20 30 40],即从索引1到3的元素。

切片多维数组

在多维数组中,你可以使用切片来获取行、列或子数组。例如,创建一个二维数组:
这将输出 [4 5 6],表示我们获取了第二行的所有元素。
这将输出 [3 6 9],表示我们获取了第三列的所有元素。

高级切片

NumPy允许使用更高级的切片操作,如跳跃切片、布尔值切片等,以满足更复杂的需求。例如,通过布尔值切片,可以根据某个条件选择数组中的元素。
这将输出 [3 4 5],表示我们选择了大于2的元素。
继续我们的探讨,下一个要点是数组形状修改。在NumPy中,你可以轻松地改变数组的形状以满足你的需求。

1.3 数组形状修改

使用reshape()方法

reshape()方法允许改变数组的形状,而不改变其数据。例如,创建一个一维数组,然后将其形状改变为二维数组:
这将输出一个二维数组:

使用ravel()flatten()方法

需要将多维数组转换为一维数组,这时可以使用 ravel()flatten() 方法。
这两种方法都会将多维数组转换为一维数组,不过 ravel() 有时会返回视图(视图与原数组共享数据),而 flatten() 总是返回数组的副本(新数组)。

注意事项

在使用 reshape() 进行形状修改时,需要确保新形状兼容原数组的大小。否则,将会收到 ValueError 错误。例如,尝试将一个包含6个元素的一维数组改为3x3的形状将导致错误。

1.4 数组数据类型

默认数据类型

当创建一个数组时,NumPy会根据输入的数据自动选择一个合适的数据类型。例如,创建一个包含整数的数组,NumPy通常会使用整数数据类型。

显示指定数据类型

需要显式指定数组的数据类型,以确保计算的精度或满足特定需求。可以使用dtype参数来指定数据类型:

数据类型的影响

不同的数据类型会影响数组的内存占用和数值精度。例如,浮点数通常会占用更多内存,但具有更高的数值精度,而整数占用较少内存,但精度有限。

数据类型转换

使用astype()方法来将数组的数据类型转换为其他类型:

1.5 数组转换与复制

数组的数据类型转换

在前面的部分,已经讨论了如何使用 astype() 方法将数组的数据类型转换为其他类型。这对于将数组从一个数据类型转换为另一个数据类型非常有用。例如:

复制和视图

当你对数组执行操作时,有时会创建原始数组的副本,有时会创建一个视图,它与原始数组共享数据。这可能会导致一些不同的行为。
  • 副本:如果你明确要创建一个新的独立副本,可以使用 copy() 方法。
  • 视图:在某些情况下,切片和形状修改操作会返回一个视图,而不是副本。这表示数据在原始数组和视图之间共享。

引用和复制的区别

理解视图和副本的区别非常重要。修改视图可能会影响原始数组,而修改副本则不会。例如:
在上面的例子中,原始数组中的值也被修改为 [1, 99, 3, 4, 5],因为切片是一个视图,与原始数组共享数据。
在这个例子中,原始数组保持不变,因为我们在副本上进行了修改

2. 数组索引与切片

2.1 一维数组的索引与切片

在NumPy中,一维数组的索引和切片操作非常类似于Python中的列表。示例:
这些是一维数组索引和切片的基本操作。通过索引获取单个元素,通过切片获取子数组,使用负数索引从尾部开始计数,以及使用步长切片来创建新的数组。

2.2 二维和多维数组的索引与切片

在二维和多维数组中,索引和切片操作稍微复杂一些,因为需要考虑多个维度。示例:
在二维和多维数组中,使用逗号分隔的索引来访问不同维度的元素。还可以使用切片来获取行、列或子矩阵。
非常好,让我们继续探讨数组运算与广播,这是NumPy中非常重要的概念,允许你进行元素级别的运算以及应用数学函数和线性代数函数。

3. 数组运算与广播

3.1 元素级别的运算

NumPy数组支持元素级别的运算,可以对数组的每个元素进行操作,而不必编写循环。
这些是一些常见的元素级别运算示例,但NumPy支持更多运算,包括三角函数、指数函数等。

3.2 广播

广播是NumPy中强大的特性之一,它允许对不同形状的数组进行运算。当你对不同形状的数组进行运算时,NumPy会自动扩展较小的数组以匹配较大的数组,使它们具有相同的形状,然后执行运算
例如,将一个标量(如单个数字)与数组相乘:
在这个示例中,标量2被广播到数组arr的每个元素上,以执行元素级别的乘法运算。
广播也适用于不同形状的数组,只要它们在某些维度上具有相同的大小。例如,将一个一维数组与一个二维数组相加:
在这个示例中,一维数组arr1被广播到与二维数组arr2相同的形状,以执行元素级别的加法运算。
广播是NumPy中强大的功能,能够执行各种不同形状的数组之间的运算,而无需显式编写循环。
这是数组运算与广播的基础知识,NumPy提供了丰富的数学函数和线性代数函数,可以应用于数组,以进行更复杂的数学和统计分析。
继续我们的学习,下一个要点是数组统计与排序,在NumPy中,你可以轻松地执行各种统计操作和数组排序。

4. 数组统计与排序

4.1 数组的统计操作

NumPy提供了一系列用于计算数组统计量的函数,如最大值、最小值、平均数、中位数、方差、标准差等。
下面是一些常见的统计函数示例:
这些函数可用于一维数组,也可以用于多维数组,并通过指定axis参数来沿指定轴进行计算。
首先,创建一个二维数组,以进行示例:

沿行进行统计

沿行计算统计量,例如每行的平均值,可以使用axis参数指定轴0(行轴):
这将计算每一列的平均值,结果为 [33.66666667 28.66666667 7.66666667 24.66666667]

沿列进行统计

沿列计算统计量,例如每列的最大值,可以使用axis参数指定轴1(列轴):
这将计算每一行的最大值,结果为 [45 56 43]
这是一个简单的案例,说明如何使用axis参数来沿指定轴执行统计操作。可以使用相同的方法来计算其他统计量,如最小值、中位数、方差等。

4.2 数组的排序

NumPy还提供了用于数组排序的函数,按升序或降序对数组进行排序。下面是一些示例:
使用argsort()函数来获取排序后的索引,以便对其他数组进行相同的排序操作。
继续我们的学习,下一个要点是随机数生成,在NumPy中,你可以使用随机数生成函数生成各种类型的随机数,包括服从正态分布、均匀分布等的随机数。

5. 随机数生成

5.1 生成均匀分布的随机数

使用np.random.rand()函数生成服从均匀分布的随机数。这将生成在0到1之间均匀分布的随机数。以下是一些示例:

5.2 生成正态分布的随机数

使用np.random.randn()函数生成服从标准正态分布(均值为0,标准差为1)的随机数。以下是一些示例:

5.3 生成指定分布的随机数

NumPy还提供了其他随机数生成函数,可以生成不同分布的随机数,如二项分布、泊松分布等。使用np.random模块来探索这些函数。
这些函数非常有用,可以生成符合不同分布的随机数,以用于模拟、实验或统计分析。
非常好,我们将继续学习数组高级操作,包括布尔索引、花式索引、where函数、迭代器等。

6. 数组高级操作

6.1 布尔索引

布尔索引是一种强大的工具,用于根据某些条件从数组中选择元素。创建一个布尔数组,其中每个元素表示与条件相对应的真值,然后使用该布尔数组来选择满足条件的元素。以下是一个示例:

6.2 花式索引

花式索引是一种通过指定索引数组来获取数组元素的方式。使用整数数组来选择元素,从而创建一个新的数组。以下是一个示例:

6.3 where函数

np.where()函数是一个强大的工具,用于根据条件从数组中选择元素。它可以返回满足条件的元素的索引或实际的元素值。以下是一些示例:
np.where()函数是一个非常灵活的工具,它可以在不同的条件下返回不同的结果。

6.4 迭代器

NumPy数组可以使用Python标准的for循环进行迭代,但更常见的做法是使用NumPy提供的迭代器。以下是一个示例:
继续我们的学习,下一个要点是数组合并和拆分,在NumPy中,你可以使用各种函数来将多个数组合并成一个数组,或将一个数组拆分成多个部分。

7. 数组合并和拆分

7.1 数组合并

在NumPy中,可以用不同的函数来合并多个数组,如 vstackhstackconcatenate 等。以下是一些示例:
  • vstack 函数用于垂直堆叠(按行堆叠)多个数组:
结果是一个新的数组,其中包含两个输入数组按行堆叠在一起。
  • hstack 函数用于水平堆叠(按列堆叠)多个数组:
结果是一个新的数组,其中包含两个输入数组按列堆叠在一起。
  • concatenate 函数允许你指定要沿着哪个轴合并数组:

7.2 数组拆分

NumPy也提供了函数来拆分数组,如 splithsplitvsplit。以下是一些示例:
  • split 函数可以将数组沿指定轴拆分成多个部分:
结果是一个包含拆分后的数组部分的列表。
  • hsplit 函数用于水平拆分数组,vsplit 用于垂直拆分数组:
这些函数允许你按照指定轴将数组拆分为多个部分。

8. 广义表与轴

8.1 广义表

广义表是一种由嵌套列表或多维数组组成的数据结构,它可以表示树状、分层结构的数据。在NumPy中,多维数组通常被视为广义表,其中每个维度对应于数据的一个层次结构。
例如,考虑一个包含学生成绩的二维数组,其中第一个维度表示不同的课程,第二个维度表示不同的学生。这可以被视为广义表,其中每个课程有一组学生成绩。以下是一个示例:

8.2 轴

在NumPy中,轴是表示数组的维度的对象。对于二维数组,通常有两个轴:0轴表示行,1轴表示列。对于三维数组,会有三个轴,以此类推。
轴在NumPy中非常重要,因为它们允许你在多维数组中执行各种操作。例如,可以使用轴来计算每一行或每一列的总和、平均值等。
以下是一些示例:
理解NumPy数组的内存布局对于数组的性能优化至关重要。NumPy支持两种主要的内存布局方式:C风格和Fortran风格,并提供strides属性来自定义数组的内存布局。让我们详细了解这些概念。

9. 数组的内存布局

9.1 C风格内存布局

C风格内存布局是NumPy中的默认方式,它与大多数编程语言的内存布局一致,数据以行为主存储。在C风格内存布局中,数组的元素在内存中是按行存储的,即相邻元素在相邻内存位置中。
下面是一个示例:

9.2 Fortran风格内存布局

Fortran风格内存布局与C风格相反,它以列为主存储数据。在Fortran风格内存布局中,数组的元素在内存中是按列存储的,即相邻元素在相邻内存位置中。
下面是一个示例:

9.3 自定义数组内存布局

NumPy还允许自定义数组的内存布局,通过使用strides属性。strides是一个元组,指定了在每个维度上跨越数组元素所需的字节数。可以使用strides属性来创建一个不连续的数组,以满足特定的需求。
下面是一个示例,创建一个具有自定义内存布局的数组:
通过自定义strides属性,可以创建特定内存布局的数组,以满足性能和数据处理需求。

10结构化数据

结构化数组是NumPy中的一个重要概念,它允许创建类似表格或数据库中的数据结构,每个元素都包含多个字段,可以使用字段名或下标来访问和操作数据。结构化数组通常用于处理异构数据,例如,每个元素包含不同类型的数据,如字符串、整数、浮点数等。
以下是如何创建和使用结构化数组的基本示例:
在这个示例中,我们首先定义了结构化数组的数据类型,其中包含三个字段:'name'(字符串类型,最大长度为10),'age'(整数类型),'weight'(浮点数类型)。然后,我们创建了一个空的结构化数组,并向其中添加数据,最后通过字段名访问数组中的数据。

11矩阵计算

NumPy提供了专门的矩阵类matrix,以及针对矩阵的一些特定运算函数,使矩阵计算更方便。虽然NumPy中的多维数组(ndarray)可以执行矩阵计算,但matrix类提供了更直观的语法和一些额外的矩阵运算功能。
以下是一些关于矩阵计算的基本示例:
在上述示例中,首先创建了两个矩阵matrix1matrix2,然后进行了矩阵乘法、求逆矩阵和矩阵转置的操作。matrix类提供了更直观的运算符重载,使矩阵计算更容易理解。
虽然matrix类在某些情况下很有用,但在实际应用中,NumPy多维数组(ndarray)仍然是更通用和灵活的数据结构,因为它们支持更多的数学和科学计算操作,并且在生态系统中更为广泛使用。

参考

Python数据分析-matplotlibpython数据分析-pandas
宓翊23
宓翊23
博学而笃志,切问而近思~ 爱探索,热爱技术的Geek一枚~
Announcement
type
status
date
slug
summary
tags
category
icon
password
🎉欢迎来到我的博客🎉
工具-资源-技术-随笔
--- 感谢您的支持 ---
👏希望能帮助到您👏
主博客:作者站点中的bevis23