1 简介
NumPy 是用于处理数组的 python 库,部分用 Python 编写,但是大多数需要快速计算的部分都是用 C 或 C ++ 编写的。它还拥有在线性代数、傅立叶变换和矩阵领域中工作的函数。NumPy 由 Travis Oliphant 于 2005 年创建。它是一个开源项目,您可以自由使用它。NumPy 指的是数值 Python(Numerical Python)。
在 Python 中,我们有满足数组功能的列表,但是处理起来很慢。NumPy 旨在提供一个比传统 Python 列表快 50 倍的数组对象。与列表不同,NumPy 数组存储在内存中的一个连续位置,因此进程可以非常有效地访问和操纵它们。这种行为在计算机科学中称为引用的局部性。这是 NumPy 比列表更快的主要原因。它还经过了优化,可与最新的 CPU 体系结构一同使用。NumPy 中的数组对象称为 ndarray,它提供了许多支持函数,使得利用 ndarray 非常容易。数组在数据科学中非常常用,因为速度和资源非常重要。
2 NumPy 入门
2.1 安装NumPy
pip install numpy
如果安装失败,可指定国内源安装,例:指定豆瓣源。
pip install numpy -i http://pypi.douban.com/simple/
2.2 导入NumPy
import numpy as np arr = np.array([1, 2, 3, 4, 5]) print(arr)
2.3 检查 NumPy 版本
import numpy as np print(np.__version__)
3 NumPy的基本操作
3.1 数组创建
import numpy as np #0维 arr = np.array(61) #一维 arr1 = np.array([1, 2, 3, 4, 5]) #二维 arr2= np.array([[1, 2, 3], [4, 5, 6]]) #三维 arr3= np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]) #检查维数 print(arr3.ndim) #创建高维数组 arr5= np.array([1, 2, 3, 4], ndmin=5) print(arr5) print('number of dimensions :', arr5.ndim)
3.2 数组索引
import numpy as np #访问数组元素 #NumPy 数组中的索引以 0 开头,这意味着第一个元素的索引为 0,第二个元素的索引为 1,以此类推。 arr = np.array([1, 2, 3, 4]) print("第一个元素:",arr[0]) print("第三个元素和第四个元素相加:",arr[2] + arr[3]) #访问2维数组 arr = np.array([[1,2,3,4,5], [6,7,8,9,10]]) print('第一维中的第二个元素: ', arr[0, 1]) #访问3维数组 arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) print("第一个数组的第二个数组的第三个元素",arr[0, 1, 2]) #负索引。使用负索引从尾开始访问数组。 arr = np.array([[1,2,3,4,5], [6,7,8,9,10]]) print('第二个维中的的最后一个元素: ', arr[1, -1])
运行结果:
第一个元素: 1
第三个元素和第四个元素相加: 7
第一维中的第二个元素: 2
第一个数组的第二个数组的第三个元素 6
第二个维中的的最后一个元素: 10
3.3 数组裁切
python 中裁切的意思是将元素从一个给定的索引带到另一个给定的索引。
我们像这样传递切片而不是索引:[start:end]。
我们还可以定义步长,如下所示:[start:end:step]。
如果我们不传递 start,则将其视为 0。
如果我们不传递 end,则视为该维度内数组的长度。
如果我们不传递 step,则视为 1。
实例:
import numpy as np arr = np.array([1, 2, 3, 4, 5, 6, 7]) print("裁切索引 1 到索引 5 的元素",arr[1:5]) print("裁切数组中索引 4 到结尾的元素",arr[4:]) print("裁切从开头到索引 4(不包括)的元素",arr[:4]) #负裁切 print("末尾开始的索引 3 到末尾开始的索引 1",arr[-3:-1]) print("从索引 1 到索引 5,步长为2",arr[1:5:2]) #裁切二维数组 arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]) print("从第二个元素开始,对从索引 1 到索引 4(不包括)的元素进行切片;",arr[1, 1:4])
运行结果:
裁切索引 1 到索引 5 的元素: [2 3 4 5]
裁切数组中索引 4 到结尾的元素: [5 6 7]
裁切从开头到索引 4(不包括)的元素: [1 2 3 4]
末尾开始的索引 3 到末尾开始的索引 1: [5 6]
从索引 1 到索引 5,步长为2: [2 4]
从第二个元素开始,对从索引 1 到索引 4(不包括)的元素进行切片; [7 8 9]
3.4 数组类型
默认情况下,Python 拥有以下数据类型:
- strings - 用于表示文本数据,文本用引号引起来。例如 "ABCD"。
- integer - 用于表示整数。例如 -1, -2, -3。
- float - 用于表示实数。例如 1.2, 42.42。
- boolean - 用于表示 True 或 False。
- complex - 用于表示复平面中的数字。例如 1.0 + 2.0j,1.5 + 2.5j。
NumPy 中所有数据类型的列表以及用于表示它们的字符。
- i - 整数
- b - 布尔
- u - 无符号整数
- f - 浮点
- c - 复合浮点数
- m - timedelta
- M - datetime
- O - 对象
- S - 字符串
- U - unicode 字符串
- V - 固定的其他类型的内存块 ( void )
3.5 数组副本/视图
副本和视图的区别:
副本和数组视图之间的主要区别在于副本是一个新数组,而这个视图只是原始数组的视图。副本拥有数据,对副本所做的任何更改都不会影响原始数组,对原始数组所做的任何更改也不会影响副本。视图不拥有数据,对视图所做的任何更改都会影响原始数组,而对原始数组所做的任何更改都会影响视图。
实例:
import numpy as np #副本 arr = np.array([1, 2, 3, 4, 5]) x = arr.copy() arr[0] = 61 print(arr) print(x) #视图 arr1 = np.array([1, 2, 3, 4, 5]) x1 = arr.view() arr1[0] = 61 print(arr1) print(x1)
运行结果:
[61 2 3 4 5]
[1 2 3 4 5]
[61 2 3 4 5]
[61 2 3 4 5]
3.6 数组形状
数组的形状是每个维中元素的数量。
import numpy as np #获取数组的形状 arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) print(arr.shape)
3.7 数组重塑
重塑意味着更改数组的形状。数组的形状是每个维中元素的数量。通过重塑,我们可以添加或删除维度或更改每个维度中的元素数量
import numpy as np #从 1-D 重塑为 2-D arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) newarr = arr.reshape(4, 3) print(newarr) #从 1-D 重塑为 3-D arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) newarr = arr.reshape(2, 3, 2) print(newarr) #展平数组 arr = np.array([[1, 2, 3], [4, 5, 6]]) newarr = arr.reshape(-1) print(newarr)
3.8 数组重塑
迭代意味着逐一遍历元素。当我们在 numpy 中处理多维数组时,可以使用 python 的基本 for 循环来完成此操作。如果我们对 1-D 数组进行迭代,它将逐一遍历每个元素。
import numpy as np #迭代1维 arr = np.array([1, 2, 3]) for x in arr: print(x) arr = np.array([[1, 2, 3], [4, 5, 6]]) #迭代2维 for x in arr: print(x) for x in arr: for y in x: print(y) #迭代3维 arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) for x in arr: print(x) for x in arr: for y in x: for z in y: print(z) #使用 nditer() 迭代数组 for x in np.nditer(arr): print(x) #以字符串形式遍历数组: for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']): print(x) # ndenumerate() 进行枚举迭代 #枚举以下 1D 数组元素: arr = np.array([1, 2, 3]) for idx, x in np.ndenumerate(arr): print(idx, x) #枚举以下 2D 数组元素: arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) for idx, x in np.ndenumerate(arr): print(idx, x)
3.9 数组连接
连接两个数组:
import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) arr = np.concatenate((arr1, arr2)) print(arr)
沿着行 (axis=1) 连接两个 2-D 数组:
import numpy as np arr1 = np.array([[1, 2], [3, 4]]) arr2 = np.array([[5, 6], [7, 8]]) arr = np.concatenate((arr1, arr2), axis=1) print(arr) print(arr.shape)
使用堆栈函数连接数组
堆栈与级联相同,唯一的不同是堆栈是沿着新轴完成的。我们可以沿着第二个轴连接两个一维数组,这将导致它们彼此重叠,即,堆叠(stacking)。我们传递了一系列要与轴一起连接到 concatenate() 方法的数组。如果未显式传递轴,则将其视为 0
import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) arr = np.stack((arr1, arr2), axis=1) print(arr) print(arr.shape)
沿不同方向堆栈
import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) arr3 = np.array([7, 8, 9]) #沿行堆叠 arr = np.hstack((arr1, arr2,arr3)) print(arr) print(arr.shape) #沿列堆叠 arr = np.vstack((arr1, arr2,arr3)) print(arr) print(arr.shape) #沿行堆叠 arr = np.dstack((arr1, arr2,arr3)) print(arr) print(arr.shape)
运行结果:
[1 2 3 4 5 6 7 8 9]
(9,)
[[1 2 3]
[4 5 6]
[7 8 9]]
(3, 3)
[[[1 4 7]
[2 5 8]
[3 6 9]]]
(1, 3, 3)
3.10 数组拆分
拆分是连接的反向操作。连接(Joining)是将多个数组合并为一个,拆分(Spliting)将一个数组拆分为多个。我们使用 array_split() 分割数组,将要分割的数组和分割数传递给它。
import numpy as np arr = np.array([1, 2, 3, 4, 5, 6]) newarr = np.array_split(arr, 3) print(newarr)
分割二维数组
import numpy as np arr = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]) newarr = np.array_split(arr, 3) print(newarr) #使用 hsplit() 方法将 2-D 数组沿着行分成三个 2-D 数组 newarr = np.hsplit(arr, 3)
3.11 数组搜索
数组中搜索(检索)某个值,然后返回获得匹配的索引。要搜索数组,请使用 where() 方法
import numpy as np arr = np.array([[1, 2, 3, 4, 5, 4, 4],[2, 2, 4, 3, 5, 4, 6]]) x = np.where(arr == 4) print(x) #将新值赋予索引结果 arr[x] =7 print(arr)
# 将所有4改为为0
array = np.where(arr==4, 0, arr)
运行结果:
(array([0, 0, 0, 1, 1], dtype=int64), array([3, 5, 6, 2, 5], dtype=int64))
[[1 2 3 7 5 7 7]
[2 2 7 3 5 7 6]]
3.12 数组过滤
直接从数组创建过滤器
import numpy as np arr = np.array([61, 62, 63, 64, 65]) filter_arr = arr > 62 newarr = arr[filter_arr] print(filter_arr) print(newarr)
3.13 随机
生成一个 0 到 100 之间的随机浮点数:
from numpy import random #生成一个 0 到 100 之间的随机整数: x1 = random.randint(100) print(x1) #random 模块的 rand() 方法返回 0 到 1 之间的随机浮点数 #生成一个 0 到 100 之间的随机浮点数 x2 = random.rand()*100 print(x2)
生成随机数组
from numpy import random #生成一个 1-D 数组,其中包含 5 个从 0 到 100 之间的随机整数: x=random.randint(100, size=(5)) print(x) 生成有 3 行的 2-D 数组,每行包含 5 个从 0 到 100 之间的随机整数: x2 = random.randint(100, size=(3, 5)) print(x2) #生成包含 5 个随机浮点数的 1-D 数组: x3 = random.rand(5) print(x3)
从数组生成随机数
choice() 方法使您可以基于值数组生成随机值。方法将数组作为参数,并随机返回其中一个值。
from numpy import random x = random.choice([3, 5, 7, 9]) print(x) x2 = random.choice([3, 5, 7, 9], size=(3, 5)) print(x2)