首先,小伙伴们要非常清楚这么一点:NumPy 就是用来操作数组的。所以我们学习 NumPy,其实就是学习数组的各种操作。了解这一点,可以让后续的学习变得更加清晰。
在 Python 中,我们可以使用 NumPy 来生成一个数组。数组和列表很相似,但它们之间是有着本质上的区别的。
- 列表的元素可以是不同数据类型,而数组的元素必须是同一数据类型。
- 列表不可以进行四则运算,而数组可以进行四则运算。
对于 NumPy 中的数组,你可以简单把它看成是一种 “增强版的列表”,因为它的功能比列表强大得多。
NumPy 创建数组
想要创建一个 NumPy 数组,最常见的是使用 numpy.array() 函数来实现。numpy.array() 接收一个列表或元组作为参数,然后返回一个 ndarray 对象。
语法:
numpy.array(列表或元组)说明:
array() 函数的参数可以是一个列表,也可以是一个元组。array() 函数其实非常简单,它其实就是将一个列表转换为一个数组,或者将一个元组转换成一个数组。
示例 1:将列表转换数组
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
print(arr.dtype)运行结果如下。
[1 2 3 4 5]
<class 'numpy.ndarray'>
int64分析:
从运行结果可以看出,数组元素之间是用空格隔开的,而不是用逗号隔开的,这一点和列表不一样。dtype 属性用于获取数组元素的类型,这个在 “NumPy 数据类型” 这一节中已经接触过了。
array() 函数会自动根据 “列表元素的类型” 来推断 “数组元素的数据类型”。np.array() 返回的是一个 ndarray 对象,这个 ndarray 对象非常重要,我们在后面会大量接触到,小伙伴们先记一下。
可能小伙伴会问:“为什么要将一个列表转换成数组呢?” 原因很简单,对于一个列表来说,我们只能使用列表的函数来进行操作。但是将列表转换成数组之后,我们就可以使用数组提供的丰富函数来进行操作了。
示例 2:将元组转换数组
import numpy as np
arr = np.array((1, 2, 3, 4, 5))
print(arr)
print(type(arr))
print(arr.dtype)运行结果如下。
[1 2 3 4 5]
<class 'numpy.ndarray'>
int64分析:
array() 函数除了可以将一个列表转换成数组,还可以将一个元组转换成数组。不过在实际开发中,我们更多的是将一个列表转换成数组。
NumPy 创建数组的函数有很多,array() 只是最常用的一种。更多关于 NumPy 创建数组的方式,我们在后面 “NumPy 创建数组” 这一节会详细介绍。
NumPy 数组属性
在 NumPy 中,一个数组就是一个 ndarray 对象。ndarray,其实就是 “n dimension array(N 维数组)” 的意思。对于一个数组来说,它的属性非常多,常用的如下表所示。
| 属性 | 说明 |
|---|---|
| ndim | 维度的个数,即多少维 |
| shape | 数组的形状,比如 m 行 n 列 |
| size | 元素的个数 |
| dtype | 元素的类型 |
ndim 是 “n dimension(N维)” 的缩写,dtype 是 “data type(数据类型)” 的缩写。从英文意思的角度,可以更好地帮助我们了解这些属性的作用。
示例 3:一维数组的属性
import numpy as np
nums = [1, 2, 3, 4, 5, 6, 7, 8]
arr = np.array(nums)
print(arr.ndim)
print(arr.shape)
print(arr.size)
print(arr.dtype)运行结果如下。
1
(8,)
8
int64分析:
从结果可以看出来,arr 的维度是 1,表示这是一个一维数组。此外 arr 的形状是 (8,),元素的个数是 8,元素的类型是 int64(即 64 位整数)。
示例 4:二维数组的属性
import numpy as np
nums = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr = np.array(nums)
print(arr.ndim)
print(arr.shape)
print(arr.size)
print(arr.dtype)运行结果如下。
2
(2, 4)
8
int64分析:
从结果可以看出来,arr 的维度是 2,表示这是一个二维数组。arr 的形状是 (2, 4),表示这是一个 2 × 4 的数组。然后元素的个数是 8,元素的类型是 int64。
示例 5:三维数组的属性
import numpy as np
nums = [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]
arr = np.array(nums)
print(arr.ndim)
print(arr.shape)
print(arr.size)
print(arr.dtype)运行结果如下。
3
(2, 2, 3)
12
int64分析:
从结果可以看出来,arr 的维度是 3,表示这是一个三维数组。arr 的形状是 (2, 2, 3),表示这是一个 2 × 2 × 3 的数组。然后元素的个数是 12,元素的类型是 int64。
“数组形状” 这个概念非常重要,在后面的学习中也会经常接触到,小伙伴们一定要理解清楚。
常见问题
1. 我们经常说起 “数组的类型” ,它的意思指的是什么呢?
在 NumPy 中,对于一个数组来说,它每一个元素的类型都是相同的。所以我们说起一个数组的类型,其实指的就是它元素的类型。
了解这一点是非常重要的,很多小伙伴们觉得 “数组的类型” 这种叫法有问题,其实并非如此。
NumPy 数组操作
在 NumPy 中,对于数组元素的操作,主要包括 “增删查改” 这 4 种方式,如下所示。
- 访问元素(查)。
- 修改元素(改)。
- 添加元素(增)。
- 删除元素(删)。
1. 访问元素
在 NumPy 中,我们也是使用下标的方式来访问数组中的元素,这一点和 Python 中的列表是一样的。
示例 6:一维数组访问元素
import numpy as np
nums = [3, 9, 1, 12, 50, 21]
arr = np.array(nums)
print(arr[0])
print(arr[1])
print(arr[2])运行结果如下。
3
9
1示例 7:二维数组访问元素
import numpy as np
nums = [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]
arr = np.array(nums)
print(arr[1][2])运行结果如下。
6分析:
对于二维数组来说,我们可以使用 arr[行索引][列索引]或 arr[行索引,列索引] 的方式访问元素。对于上面例子来说,如果想要获取第 2 行第 3 列的元素,可以使用以下 2 种方式:
arr[1][2]
arr[1, 2]需要注意的是,不管是行还是列,下标都是从 0 开始的。有一句话说得好,一切从 0 开始嘛。
示例 8:负数下标
import numpy as np
nums = [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]
arr = np.array(nums)
print(arr[-1][-1])
print(arr[-1][-2])运行结果如下。
10
8分析:
和列表一样,我们还可以使用负数的下标。比如想要获取最后一行最后一个元素,可以这样来写:arr[-1][-1]或 arr[-1, -1]。
2. 修改元素
在 NumPy 中,我们也是使用下标的方式来修改某一个元素的值。对于二维数组来说,我们还可以修改整一行或整一列的值。
示例 9:修改数组的元素
import numpy as np
arr = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
arr[2][2] = 99
arr[1] = [44, 55, 66]
print(arr)运行结果如下。
[[10 20 30]
[44 55 66]
[70 80 99]]分析:
arr[2][2] = 99 表示将第 3 行第 3 列元素的值修改为 99,arr[1] = [44, 55, 66] 表示将第 2 行的值修改为 [44, 55, 66]。
3. 添加元素
在 NumPy 中,我们可以使用 numpy.append() 函数在数组的末尾添加一个新元素,类似于 “Python 列表 append() 方法” 。
语法:
numpy.append(arr, value, axis=n)说明:
arr 是一个数组,value 是新元素。axis 是从 0 开始的整数,它用于定义沿着哪一条轴进行操作。
对于一维数组来说,我们不需要用到 axis 这个参数。对于二维数组来说,axis 的值可以是 0 或 1。二维数组有两个维度:如果 axis=0,那么 axis=1 这一维的形状要相同;如果 axis=1,那么 axis=0 这一维的形状要相同。所谓的形状,就是 “(行数, 列数)”。对于数组的形状,我们可以通过 shape 属性来获取。
append() 函数并不会修改原来的数组,而是返回一个新的数组。小伙伴请记住一个非常重要的结论:一般来说,NumPy 提供的函数都不会修改原数组。了解这一点,可以让你后续的学习更加清晰。
示例 10:一维数组添加元素
import numpy as np
arr = np.array([1, 2, 3, 4])
result = np.append(arr, 5)
print(arr)
print(result)运行结果如下。
[1 2 3 4]
[1 2 3 4 5]分析:
从结果可以看出来,append() 函数并不会修改原数组,而是返回一个新数组。
示例 11:二维数组(axis=0)
import numpy as np
arr = np.array([[10, 20, 30, 40], [50, 60, 70, 80]])
result = np.append(arr, [[11, 22, 33, 44]], axis=0)
print(arr)
print(result)运行结果如下。
[[10 20 30 40]
[50 60 70 80]]
[[10 20 30 40]
[50 60 70 80]
[11 22 33 44]]分析:
axis=0 表示沿着 “纵轴” 方向进行操作,所以我们这里改变的是 “行”,然后 “列” 不变。对于 axis=0 来说,我们要求两个数组的列数必须相同。如果列数不同,就会报错。
示例 12:二维数组(axis=1)
import numpy as np
arr = np.array([[10, 20, 30, 40], [50, 60, 70, 80]])
result = np.append(arr, [[11, 22], [33, 44]], axis=1)
print(arr)
print(result)运行结果如下。
[[10 20 30 40]
[50 60 70 80]]
[[10 20 30 40 11 22]
[50 60 70 80 33 44]]分析:
axis=1 表示沿着 “横轴” 方向进行操作,所以我们这里改变的是 “列”,然后 “行” 不变。对于 axis=1 来说,我们要求两个数组的行数必须相同。如果行数不同,就会报错。
示例 13:二维数组(axis 为空)
import numpy as np
arr = np.array([[10, 20, 30, 40], [50, 60, 70, 80]])
result1 = np.append(arr, [11, 22, 33, 44])
result2 = np.append(arr, [[11, 22, 33, 44]])
result3 = np.append(arr, [[11, 22], [33, 44]])
print(result1)
print(result2)
print(result3)运行结果如下。
[10 20 30 40 50 60 70 80 11 22 33 44]
[10 20 30 40 50 60 70 80 11 22 33 44]
[10 20 30 40 50 60 70 80 11 22 33 44]分析:
当 axis 为空时,append() 函数会直接将两个数组 “打平” 成一维数组,然后再进行合并。对于 axis 为空的情况,在实际开发中用得极少,这里我们简单了解一下即可。
4. 删除元素
在 NumPy 中,我们可以使用 numpy.delete() 函数来删除元素。numpy.delete() 函数不仅可以删除某一个元素,还可以删除某一行或某一列。
语法:
numpy.delete(arr, m, axis=n)说明:
arr 是一个数组,m 是第 m 行或第 m 列。对于二维数组来说,当 axis=0 时,表示删除第 m 行;当 axis=1 时,表示删除第 m 列。
同样地,delete() 函数并不会修改原数组,而是返回一个新数组。
示例 14:一维数组删除元素
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
result = np.delete(arr, 2)
print(arr)
print(result)运行结果如下。
[10 20 30 40 50]
[10 20 40 50]分析:
np.delete(arr, 2) 表示删除 arr 中的第 3 个元素,然后返回一个新数组。
示例 15:二维数组删除元素
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 删除第3行
result1 = np.delete(arr, 2, axis=0)
# 删除第3列
result2 = np.delete(arr, 2, axis=1)
print(arr)
print(result1)
print(result2)运行结果如下。
[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]]
[[1 2]
[4 5]
[7 8]]分析:
我们要非常清楚一点:在 NumPy 中,对二维数组的删除操作,一般都是删除整一行或整一列,很少会去删除某一个元素。
