Numpy
介绍
-
一个python的库, 一个做多维数组运算的工具
-
它相比python自带的数组的优势是代码简单、效率高。
无论是c还是python都需要进行循环,代码较为复杂且循环效率低下。
-
为什么numpy会这么快?
它的底层逻辑是c
安装
conda install numpy
可以在notebook或者终端里直接安装
创建和生成Numpy数组
要复习一下python的语法
-
从python列表或元组创建
-
从列表创建
list_array = np.array([1, 2, 3])
-
从列表创建二维数组
list_2d_array = np.array([[1, 2., 3], [4, 5, 6]])
-
指定数据类型(shift+tab可以查看官方的文档)
typed_array = np.array([1, 2, 3], dtype=np.float16)
-
从元组创建
tuple_array = np.array((1.1, 2.2))
-
从元组创建二维数组
tuple_2d_array = np.array([(1.1, 2.2, 3.3), (4.4, 5.5, 6.6)])
-
-
用arange生成数组
-
创建从0到11的数组,前闭后开
arange_array = np.arange(12)
-
创建一个步长为2的数组
stepped_array = np.arange(100, 124, 2)
-
-
使用linspace和logspace生成数组
-
使用linspace创建等间隔的数组
linear_space = np.linspace(0, 9, 10)
使用 linspace 创建的数组: [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
-
使用logspace创建对数间隔数值的数组
logarithmic_space = np.logspace(0, 9, 10, base=np.e)
使用 logspace 创建的数组: [1.00000000e+00 2.71828183e+00 7.38905610e+00 2.00855369e+01 5.45981500e+01 1.48413159e+02 4.03428793e+02 1.09663316e+03 2.98095799e+03 8.10308393e+03]
注意事项:
-
linspace
的第三个参数是数组中的元素数量,而不是步长。 -
logspace
的base
参数默认为 10,可以生成不同基数的对数间隔数组。
-
-
使用ones和zeros创建数组
-
创建全0/1的数组
ones_array = np.ones((2, 3))
-
创建与另一个数组形状相同的全0
zeros_array = np.zeros((2, 3, 4))
-
-
使用random生成随机数
老用法:
-
创建一个2×3的随机数组,元素值介于0到1之间
np.random.rand(2, 3)
-
元素值介于0到10之间
np.random.randint(0, 10, (2, 3))
-
创建正态分布
np.random.randn(2, 4)
新用法:
-
使用Generator的方法来生成随机数
rng是一个Generator
rng = np.random.default_rng(42)
-
连续均匀分布用法
rng.random((2, 3))
-
可以指定上下界
rng.uniform(0, 5, (2, 3))
-
指定大小和上界
rng.integers(10, size=2)
-
指定上下界
rng.integers(0, 10, (2, 3))
-
标准正态分布用法
rng.standard_normal((2, 4))
-
高斯分布用法
rng.normal(0, 1, (3, 5))
-
-
从文件里读取文件
-
将数组保存到文件
np.save('./my_array', np.array([[1, 2, 3], [4, 5, 6]]))
-
从文件加载数组
loaded_array = np.load('my_array.npy')
注意别丢了.npy
-
基本统计操作
尺寸相关
-
获取数组维度
arr.ndim
-
获取数组的形状
arr.shape
-
获取数组中共有几个数据
arr.saize
最值
-
最大值
arr.max()
-
依次按列查找
arr.max(axis=0)
输出:array([0.77395605, 0.97562235, 0.85859792, 0.92676499])
-
依次按行查找
arr.max(axis=1)
输出:array([0.85859792, 0.97562235, 0.92676499])
-
要保持维度不变
arr.max(axis=0,keepdims=True)
-
平均值、求和、标准差
-
平均值
np.average(arr)
按指定的维度计算平均值
np.average(arr, axis=0)
-
求和
-
计算数组的按行求和:
np.sum(arr, axis=1)
-
保持维度不变:
np.sum(arr, axis=1, keepdims=True)
-
按列进行累计求和:
np.cumsum(arr, axis=0)
-
按行进行累计求和
np.cumsum(arr, axis=1)
-
-
标准差
按列计算标准差
np.std(arr, axis=0)
计算数组的方差
np.var(arr, axis=1)
广播机制
NumPy 的广播机制允许不同形状的数组在算术运算中进行兼容。当进行算术运算如加、减、乘、除等操作时,NumPy 试图让这些数组的形状匹配,如果可能的话,会“广播”较小数组的形状以匹配较大数组的形状。这让我们可以在不同形状的数组之间进行数学运算,而无需手动调整它们的大小。
就是当进行计算的两个数组维度不同时,低纬度的数组升维度,然后自我复制以适应高维数组。
切片与索引
最重要的!
重点提示:
-
切片和索引是在现有数组上操作以获取所需「部分」元素的方法。其核心是根据
start:stop:step
模式按维度操作数组。 -
对于不需要处理的维度统一使用
:
或...
来表示。 -
分析操作时,首先需要注意逗号「
,
」的位置。处理的维度与arange
、linspace
等函数的使用方法相同。 -
索引支持负数,即可以从数组的末尾开始计数。
切片
-
获取行的元素比较方便:
-
获取第0行的所有元素
print(arr[0])
-
获取第0行的第一个元素
print(arr[0, 1])
-
获取第1到第2行的所有元素(连续)
print(arr[1:3])
-
获取第1行和第三行的所有元素(离散)
print(arr[[1, 3]])
-
获取第1到2行的第1列元素
print(arr[1:3, 1])
-
获取第3行到最后一行的所有元素
print(arr[[1, 3], [0]])
-
获取从开始到第3行的所有元素
print(arr[3:])
-
使用步长来获取元素
print(arr[:3, 1:3])
-
-
获取列的元素要思考一下
print(arr[..., 1])
print(arr[:, 1])
拼接
在数据处理中,我们经常需要将多个数组合并成一个更大的数组。这可以通过拼接或堆叠完成。NumPy 提供了多种方法来实现这一点.
np.concatenate
想象:两页纸拼成了一张大纸
可以沿着指定的轴拼接
-
默认沿着axis=0(行):
concatenated_arr = np.concatenate((arr1, arr2))
-
也可以指定
concatenated_arr_axis1 = np.concatenate((arr1, arr2), axis=1)
np.stack
想象:两页纸摞起来了
stacked_arr = np.stack((arr1, arr2))
这个也可以制定摞的轴
stacked_arr_axis2 = np.stack((arr1, arr2), axis=2)
重复
有时我们需要将数组中的元素沿着指定的轴重复某些次数,
np.repeat
函数正是为此设计的。
-
沿着 axis=0 重复每一行两次
repeated_arr_axis0 = np.repeat(arr, 2, axis=0)
-
沿着 axis=1 重复每一列三次
repeated_arr_axis1 = np.repeat(arr, 3, axis=1)
分拆
与拼接相反,分拆是将一个大数组分割成多个小数组的过程。
np.split
提供了一个通用的分割方法。
-
默认情况下,
np.split
沿着第一个轴(axis=0)分割数组split_arr = np.split(arr, 3)
-
也可以指定沿着哪个轴
split_arr_axis1 = np.split(arr, 2, axis=1)
条件筛选
在处理数组时,我们经常根据条件选择或修改元素。
np.where
是一个非常有用的函数,它返回满足条件的元素的索引。
-
使用条件筛选来创建一个布尔数组
condition = arr > 50
-
使用
np.where
来找到满足条件的元素的索引indices = np.where(arr > 50)
-
使用
np.where
进行条件赋值,将所有小于等于 50 的元素替换为 -1new_arr = np.where(arr > 50, arr, -1)
提取
-
使用
np.extract
来提取大于 50 的元素extracted_elements = np.extract(arr > 50, arr)
-
使用
np.unique
来获取数组中所有唯一的元素unique_elements = np.unique(arr)
最值Index
在数据分析中,我们经常需要找到最大或最小元素的位置。
np.argmax
和np.argmin
可以帮助我们找到这些元素的索引。
-
找到整个数组中最大元素的索引
index_of_max = np.argmax(arr)
-
沿着列找到每列最大元素的索引
indices_of_max_in_columns = np.argmax(arr, axis=0)
-
沿着行找到每行最小元素的索引
indices_of_min_in_rows = np.argmin(arr, axis=1)
形状和转换
改变形状
用于扩展一维度的 expand_dims
和去除一维度的 squeeze
函数。这些函数在神经网络架构中尤其常见。
需要特别注意的是,无论是扩展还是压缩维度,改变的维度大小必须是 1。例如,在使用 squeeze
函数时,如果指定了具体的维度,那么该维度的大小必须是 1。
-
np.expand_dims
-
可以在指定位置增加一个维度
arr_expanded = np.expand_dims(arr, axis=1)
expanded = np.expand_dims(arr, axis=(1, 3, 4))
扩充维度时不能跳过已有的维度,不然会报错
-
-
np.squeeze
-
函数用于移除数组形状中大小为 1 的维度.
arr_squeezed = np.squeeze(expanded, axis=1)
-
移除所有大小为 1 的维度
squeezed = np.squeeze(expanded)
-
-
np.reshape/arr.reshape
-
reshape
函数可以改变数组的形状而不改变其数据。arr_reshaped = arr.reshape(2, 2, 3)
-
使用 -1 可以自动计算该维度的大小
arr_reshaped = arr.reshape((4, -1))
-
-
np.resize
注意:resize 会直接修改原数组,而不是返回一个新数组;与 reshape 不同,resize 允许新形状的总元素数量与原数组不同.
arr.resize((4, 3), refcheck=False)
arr_resized = np.resize(arr, (5, 3))
如果新形状的总元素数量少于原数组,则
np.resize
会复制原数组中的元素以填充新数组。如果新形状的总元素数量多于原数组,则 np.resize 会截断原数组中的元素.arr_resized = np.resize(arr, (2, 2))
反序
反序是将数组中的元素顺序颠倒。在
numpy
中,我们可以使用切片的方式来实现反序。
-
反序字符串
s = "uevol" s_reversed = s[::-1] print(s_reversed)
-
反序列表
lst = [1, "1", 5.2] lst_reversed = lst[::-1] print(lst_reversed)
-
反序 numpy 数组;默认情况下,使用切片 -1 可以反序数组的最外层维度
arr_reversed = arr[::-1]
-
可以在不同的维度上进行反序操作,例如,反序所有维度
arr_reversed_all_dims = arr[::-1, ::-1]
转置
转置是线性代数中的一个基本操作,它将矩阵的行与列交换。在
numpy
中,这个操作可以很容易地通过.T
属性或np.transpose
函数来完成。需要注意的是,一维数组的转置与原数组相同,因为它只有一个维度。
-
多维数组的转置
arr_transposed = arr.T
-
arr.T
arr.T
是转置的简便方法,适用于二维数组。对于多维数组,它会将所有维度的顺序倒置。 -
np.transpose
np.transpose
函数提供了更多的灵活性,允许您指定转置的维度顺序。使用 np.transpose 进行转置
arr_transposed = np.transpose(arr)