目录
NumPy提供了两种基本的对象:ndarry 和 ufunc。ndarray是一个具有矢量算术运算和复杂广播能力的、快速且节省空间的多维且数组,ufunc则提供了对ndarray进行快速运算的标准数学函数。
1、ndarray创建与索引
1.1创建ndarray对象
在Numpy中,创建ndarray的方法根据创建的ndarray不同,可以有函数array、arange、linspace、logspace、zeros、eye、diag、ones等。此外,Numpy还提供随机数相关函数,,也可以用于创建ndarray。
1.1.1ndarray数据类型
import numpy as np
print(f"整数42转为浮点数结果为:{np.float64(42)}")
print(f"整数42转为布尔值结果为:{np.bool_(42)}")
运行结果:
整数42转为浮点数结果为:42.0
整数42转为布尔值结果为:True
1.1.2 ndarray创建
创建一维ndarray和二维ndarray
import numpy as np
arr0 = np.array((1, 2, 3, 4, 5)) # 括号内为元组
arr1 = np.array([1, 2, 3, 4]) # 括号内为列表
arr2 = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 10, 11]])
arr4 = np.array(range(10)) # 迭代对象
arr5 = np.array([i ** 2 for i in range(5)]) # 迭代对象
print(f"创建的一维ndarray为:{arr0}")
print(f"创建的一维ndarray为:{arr1}")
print(f"创建的二维ndarray为:\n{arr2}")
print(f"创建的一维ndarray为:{arr4}")
print(f"创建的一维ndarray为:{arr5}")
运行结果:
创建的一维ndarray为:[1 2 3 4 5]
创建的一维ndarray为:[1 2 3 4]
创建的二维ndarray为:
[[ 1 2 3 4]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的一维ndarray为:[0 1 2 3 4 5 6 7 8 9]
创建的一维ndarray为:[ 0 1 4 9 16]
import numpy as np
# 二维数组:嵌套序列(列表,元组均可)
arr0 = np.array([[1, 2, 3], ('a', 'c', 'd')])
print(f"arr0:\n{arr0}")
# 当嵌套序列数目不一样时
arr1 = np.array([[1, 2, 3], ('a', 'c', 'd', 'f')]) # 会有警告
print(f"arr1:\n{arr1}")
print(f"arr1 的ndim:\n{arr1.ndim}")
运行结果:
arr0:
[['1' '2' '3']
['a' 'c' 'd']]
arr1:
[list([1, 2, 3]) ('a', 'c', 'd', 'f')]
arr1 的ndim:
1
import numpy as np
# 设置元素类型
arr0 = np.array([2, 2.4, 3.6, 4.1], dtype='int')
print(f"arr0:{arr0}")
运行结果:
arr0:[2 2 3 4]
常用的ndarray的常用属性如下表:
import numpy as np
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [8, 9, 10, 11]])
print(f"arr1的轴的个数:{arr1.ndim}")
print(f"arr2的轴的个数:{arr2.ndim}")
print(f"arr1的维度:{arr1.shape}")
print(f"arr2的维度:{arr2.shape}")
print(f"arr1的元素个数:{arr1.size}")
print(f"arr2的元素个数:{arr2.size}")
print(f"arr1的数据类型:{arr1.dtype}")
print(f"arr2的数据类型:{arr2.dtype}")
print(f"arr1的每个元素字节大小:{arr1.itemsize}")
print(f"arr2的每个元素字节大小:{arr2.itemsize}")
运行结果:
arr1的轴的个数:1
arr2的轴的个数:2
arr1的维度:(4,)
arr2的维度:(3, 4)
arr1的元素个数:4
arr2的元素个数:12
arr1的数据类型:int32
arr2的数据类型:int32
arr1的每个元素字节大小:4
arr2的每个元素字节大小:4
针对一些特殊的ndarray,Numpy提供了其他的ndarray创建函数
函数 | 说明 |
arange | 创建等差数列(指定开始值、终值和步长) |
linspace | 创建等差数列(指定开始值、终值(包括)和元素个数) |
logspace | 创建等比数列 |
zeros | 创建值全为0的矩阵 |
eye | 创建单位矩阵(对角线元素为1,其余为0) |
diag | 创建对角矩阵(对角线元素为指定值,其余为0) |
ones | 创建值全部为1的矩阵 |
arange函数使用部分展示:
import numpy as np
print(f"使用arange函数创建ndarray1为:\n{np.arange(0, 10, 2)}")
print(f"使用arange函数创建ndarray2为:\n{np.arange(10, 1)}")
print(f"使用arange函数创建ndarray3为:\n{np.arange(10, step = 1)}")
运行结果:
使用arange函数创建ndarray1为:
[0 2 4 6 8]
使用arange函数创建ndarray2为:
[]
使用arange函数创建ndarray3为:
[0 1 2 3 4 5 6 7 8 9]
import numpy as np
print(f"使用arange函数创建ndarray为:\n{np.arange(0, 1, 0.1)}")
print(f"使用linspace函数创建ndarray为:\n{np.linspace(0, 1, 5)}")
# 下面创建是从1(10的0次方)到100(10的二次方),这10个元素的等比数列
print(f"使用logspace函数创建ndarray为:\n{np.logspace(0, 2, 10)}")
print(f"使用zeros函数创建ndarray为:\n{np.zeros((2, 3))}")
print(f"使用eye函数创建ndarray为:\n{np.eye(3)}")
print(f"使用diag函数创建ndarray为:\n{np.diag([2, 3, 4])}")
print(f"使用ones函数创建ndarray为:\n{np.diag((3, 2))}")
运行结果:
使用arange函数创建ndarray为:
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
使用linspace函数创建ndarray为:
[0. 0.25 0.5 0.75 1. ]
使用logspace函数创建ndarray为:
[ 1. 1.66810054 2.7825594 4.64158883 7.74263683
12.91549665 21.5443469 35.93813664 59.94842503 100. ]
使用zeros函数创建ndarray为:
[[0. 0. 0.]
[0. 0. 0.]]
使用eye函数创建ndarray为:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
使用diag函数创建ndarray为:
[[2 0 0]
[0 3 0]
[0 0 4]]
使用ones函数创建ndarray为:
[[3 0]
[0 2]]
使用随机数创建ndarray,numpy中随机数相关的函数都在random模块中。
numpy.random部分函数
import numpy as np
print(f"使用random函数生成的随机数ndarray为:\n{np.random.random(5)}")
print(f"使用rand函数生成服从均匀分布的随机数ndarray为:\n{np.random.rand(3, 5)}")
print(f"使用randint函数生成给定上下限的随机整数ndarray为:\n{np.random.randint(2, 10,[2, 3])}")
运行结果:
使用random函数生成的随机数ndarray为:
[0.09594888 0.2016682 0.84676803 0.66376245 0.2414957 ]
使用rand函数生成服从均匀分布的随机数ndarray为:
[[0.13673995 0.79574959 0.42616049 0.00760496 0.88965927]
[0.91864831 0.08410816 0.07618759 0.4229055 0.19356727]
[0.63578401 0.50782571 0.16605383 0.76282094 0.70902764]]
使用randint函数生成给定上下限的随机整数ndarray为:
[[6 9 5]
[2 9 7]]
1.1.3 ndarray的索引与切片
一维 ndarray的索引
import numpy as np
# 默认 np.arange(0, 10, 1)
arr = np.arange(10)
print(f"初始结果为:{arr}")
print(f"使用元素位置索引结果为:{arr[5]}")
print(f"使用元素位置切片结果为:{arr[2:5]}")
print(f"使用元素位置切片结果为:{arr[2:8:2]}")
print(f"省略单个位置切片结果为:{arr[:5]}")
print(f"使用元素反向位置切片结果为:{arr[:-2]}")
# 修改对应下标的值
arr[2:5] = 10, 11, 13
print(f"修改后结果为:{arr}")
运行结果为:
初始结果为:[0 1 2 3 4 5 6 7 8 9]
使用元素位置索引结果为:5
使用元素位置切片结果为:[2 3 4]
使用元素位置切片结果为:[2 4 6]
省略单个位置切片结果为:[0 1 2 3 4]
使用元素反向位置切片结果为:[0 1 2 3 4 5 6 7]
修改后结果为:[ 0 1 10 11 13 5 6 7 8 9]
多维 ndarray的索引,多维 ndarray的每个维度都有一个索引,各个维度的索引之间用逗号隔开。
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"初始结果为:\n{arr}")
# 取第二列
print(f"切片结果为:\n{arr[:, 1:2]}")
# 取1、2两行,2、3两列
print(f"切片结果为:\n{arr[0:2, 1:3]}")
# 取 arr中(0,1)、(0,2)、(2,0)的值
print(f"索引结果为:\n{arr[[0, 0, 2], [1, 2,0]]}")
# bool索引
print(f"索引结果为:\n{arr>6}")
print(f"索引结果为:\n{arr[arr>6]}")
运行结果:
初始结果为:
[[1 2 3]
[4 5 6]
[7 8 9]]
切片结果为:
[[2]
[5]
[8]]
切片结果为:
[[2 3]
[5 6]]
索引结果为:
[2 3 7]
索引结果为:
[[False False False]
[False False False]
[ True True True]]
索引结果为:
[7 8 9]
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"初始结果为:\n{arr}")
print(f"arr[...,1]切片结果为:\n{arr[...,1]}")
print(f"arr[...,1:]切片结果为:\n{arr[...,1:]}")
print(f"arr[:,1:]切片结果为:\n{arr[:,1:]}")
运作结果:
初始结果为:
[[1 2 3]
[4 5 6]
[7 8 9]]
arr[...,1]切片结果为:
[2 5 8]
arr[...,1:]切片结果为:
[[2 3]
[5 6]
[8 9]]
arr[:,1:]切片结果为:
[[2 3]
[5 6]
[8 9]]
2.2 ndarray 的基础操作
ndarray 基本操作包括,设置ndarray形状、展平ndarray、组合ndarray、分割ndarray,ndarray的排序与搜索,以及ndarray的字符串操作。
2.2.1 设置 ndarray的形状
设置 ndarray形状 Numpy提供了reshape方法,reshape 方法仅改变原始数据的形状,不改变原始数据的值,且不改变原ndarray;resize方法也提供类似·reshape的功能,但是resize方法会直接作用于所操作 ndarray。
import numpy as np
arr = np.arange(12)
print(f"创建的一维 ndarray为{arr}")
arr1 = arr.reshape(3, 4)
print(f"reshape(3, 4) ndarray为\n{arr1}")
print(f"原始 ndarray为{arr}")
arr.resize(2, 6)
print(f"经过resize()方法后原始 ndarray为\n{arr}")
运行结果:
创建的一维 ndarray为[ 0 1 2 3 4 5 6 7 8 9 10 11]
reshape(3, 4) ndarray为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
原始 ndarray为[ 0 1 2 3 4 5 6 7 8 9 10 11]
经过resize()方法后原始 ndarray为
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
2.2.2展平ndarray
将多维ndarray转换成一维ndarray的操作过程。在Numpy中,可以使用ravel方法完成ndarray的横向展平工作。flatten方法也可以完成ndarray的展平工作,区别在于flatten 方法还可以选择横向或纵向展平。
import numpy as np
arr = np.arange(12).reshape(3, 4)
print(f"创建的二维 ndarray为\n{arr}")
print(f"创建的二维 ndarray使用ravel横向展开为{arr.ravel()}")
print(f"创建的二维 ndarray使用flatten横向展开为{arr.flatten()}")
print(f"创建的二维 ndarray使用flatten纵向展开为{arr.flatten('F')}")
运行结果:
创建的二维 ndarray为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的二维 ndarray使用ravel横向展开为[ 0 1 2 3 4 5 6 7 8 9 10 11]
创建的二维 ndarray使用flatten横向展开为[ 0 1 2 3 4 5 6 7 8 9 10 11]
创建的二维 ndarray使用flatten纵向展开为[ 0 4 8 1 5 9 2 6 10 3 7 11]
2.2.3组合 ndarray
将多个 ndarray 组合为一个全新的 ndarray 的操作称为组合 ndarray。Numpy 提供横向组合、纵向组合、深度组合等多种组合方式,使用hstack、vatack、concatenate、dstack函数来完成。除了深度组合方式外,其余组合方式结果的维度于原 ndarray 相同。
使用 hstack 函数实现 ndarray横向组合(vatack同理)
import numpy as np
# 使用 hstack 函数实现 ndarray横向组合
arr = np.arange(12).reshape(3, 4)
print(f"创建的一个二维 ndarray为\n{arr}")
arr1 = arr * 3
print(f"创建的另一个二维 ndarray为\n{arr1}")
print(f"使用 hstack 函数实现 ndarray横向组合为\n{np.hstack((arr, arr1))}")
运行结果:
创建的一个二维 ndarray为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的另一个二维 ndarray为
[[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
使用 hstack 函数实现 ndarray横向组合为
[[ 0 1 2 3 0 3 6 9]
[ 4 5 6 7 12 15 18 21]
[ 8 9 10 11 24 27 30 33]]
使用 concatenate 函数实现 ndarray横/纵向组合
import numpy as np
# 使用 concatenate 函数实现 ndarray横向组合
arr = np.arange(12).reshape(3, 4)
print(f"创建的一个二维 ndarray为\n{arr}")
arr1 = arr * 3
print(f"创建的另一个二维 ndarray为\n{arr1}")
print(f"使用 concatenate 函数实现 ndarray横向组合为\n{np.concatenate((arr, arr1),axis=1)}")
print(f"使用 concatenate 函数实现 ndarray纵向组合为\n{np.concatenate((arr, arr1),axis=0)}")
运行结果:
创建的一个二维 ndarray为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的另一个二维 ndarray为
[[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
使用 concatenate 函数实现 ndarray横向组合为
[[ 0 1 2 3 0 3 6 9]
[ 4 5 6 7 12 15 18 21]
[ 8 9 10 11 24 27 30 33]]
使用 concatenate 函数实现 ndarray纵向组合为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
所谓深度组合,就是将一系列 ndarray 沿着纵轴方向进行层叠组合。Numpy提供了datack 函数可实现深度组合。
使用 datack 函数实现 ndarray深度组合
import numpy as np
# 使用 datack 函数实现 ndarray深度组合
arr = np.arange(12).reshape(3, 4)
print(f"创建的一个二维 ndarray为\n{arr}")
arr1 = arr * 3
print(f"创建的另一个二维 ndarray为\n{arr1}")
print(f"使用 datack 函数实现 ndarray深度组合为\n{np.dstack((arr, arr1))}")
运行结果:
创建的一个二维 ndarray为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
创建的另一个二维 ndarray为
[[ 0 3 6 9]
[12 15 18 21]
[24 27 30 33]]
使用 datack 函数实现 ndarray深度组合为
[[[ 0 0]
[ 1 3]
[ 2 6]
[ 3 9]]
[[ 4 12]
[ 5 15]
[ 6 18]
[ 7 21]]
[[ 8 24]
[ 9 27]
[10 30]
[11 33]]]
2.2.4 分割 ndarray
将一个 ndarray 拆分为多个 ndarray的操作称为分割 ndarray 。在Numpy中,ndarray 可以进行横向、纵向、或深度分割,使用hsplit、vsplit、split和dsplit函数实现。
import numpy as np
# 使用 hsplit 函数实现 ndarray横向分割
# 使用 vsplit 函数实现 ndarray横向分割
# 使用 split 函数实现 ndarray横向和纵向分割
arr = np.arange(12).reshape(3, 4)
print(f"创建的一个二维 ndarray为\n{arr}")
print(f"使用 hsplit 函数实现 ndarray横向分割为\n{np.hsplit(arr, 2)}")
print(f"使用 vsplit 函数实现 ndarray纵向分割为\n{np.vsplit(arr, 1)}")
print(f"使用 split 函数实现 ndarray横向分割为\n{np.split(arr, 2, axis = 1)}")
print(f"使用 split 函数实现 ndarray纵向分割为\n{np.split(arr, 1, axis = 0)}")
运行结果:
创建的一个二维 ndarray为
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
使用 hsplit 函数实现 ndarray横向分割为
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
使用 vsplit 函数实现 ndarray纵向分割为
[array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])]
使用 split 函数实现 ndarray横向分割为
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
使用 split 函数实现 ndarray纵向分割为
[array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])]
dsplit函数可实现ndarray的深度分割,但分割的 ndarray 必须是三维 ndarray.
2.2.5排序
Numpy 中排序方式概括为直接排序和间接排序两种。直接排序指对数值直接进行排序;间接排序指根据一个或多个键对数据集进行排序。
使用 sort 函数进行排序
import numpy as np
np.random.seed(42) # 设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
print(f"创建的随机数 ndarray arr为:\n{arr}")
print(f"默认排序后 ndarray arr为:\n{np.sort(arr)}")
print(f"展平排序后 ndarray arr为:\n{np.sort(arr, axis=None)}")
print(f"横轴排序后 ndarray arr为:\n{np.sort(arr, axis=1)}")
print(f"纵轴排序后 ndarray arr为:\n{np.sort(arr, axis=0)}")
运行结果:
创建的随机数 ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
默认排序后 ndarray arr为:
[[4 7 8]
[3 5 7]
[5 7 8]
[4 8 8]]
展平排序后 ndarray arr为:
[3 4 4 5 5 7 7 7 8 8 8 8]
横轴排序后 ndarray arr为:
[[4 7 8]
[3 5 7]
[5 7 8]
[4 8 8]]
纵轴排序后 ndarray arr为:
[[4 4 3]
[5 7 5]
[7 8 8]
[7 8 8]]
argsort 函数和 lexsort 函数 可以实现在给定一个或多个键时,得到一个由整数构成的索引 ndarray,索引值表示数据在新的顺序下的位置。
使用 argsort 函数进行排序
import numpy as np
np.random.seed(42) # 设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
print(f"创建的随机数 ndarray arr为:\n{arr}")
print(f"展平排序后 ndarray arr为:\n{np.argsort(arr, axis=None)}")
print(f"横轴排序后 ndarray arr为:\n{np.argsort(arr, axis=1)}")
运行结果:
创建的随机数 ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
展平排序后 ndarray arr为:
[ 5 1 9 3 8 0 4 6 2 7 10 11]
横轴排序后 ndarray arr为:
[[1 0 2]
[2 0 1]
[2 0 1]
[0 1 2]]
2.2.6搜索
NumPy 模块提供了一些用于在 ndarray 内搜索的函数,包括用于找到最大值、最小值以及满足条件的元素的函数。
argmax 与 argmin 函数用于求最大和最小值的索引。
import numpy as np
np.random.seed(42) # 设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
print(f"创建的随机数 ndarray arr为:\n{arr}")
print(f" ndarray arr中最大元素的索引为:\n{np.argmax(arr)}")
print(f" ndarray arr中最小元素的索引为:\n{np.argmin(arr)}")
print(f" ndarray arr中各列中最大元素的索引为:\n{np.argmax(arr,axis=0)}")
print(f" ndarray arr中各行最小元素的索引为:\n{np.argmin(arr,axis=1)}")
运行结果:
创建的随机数 ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
ndarray arr中最大元素的索引为:
2
ndarray arr中最小元素的索引为:
5
ndarray arr中各列中最大元素的索引为:
[0 2 0]
ndarray arr中各行最小元素的索引为:
[1 2 2 0]
numpy.where调用方式为numpy.where(condition,x,y), 满足条件的位置上返回结果x,不满足的位置上返回结果。若只有条件(condition),没有x和y,则输出满足条件元素的下标。如果没有指定返回结果,只有查找条件则返回满足条件的位置。返回的结果是一个元组(tuple),包含两个数组,第一个数组纪录的是行,第二个数组纪录的是列。
import numpy as np
np.random.seed(42) # 设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
print(f"创建的随机数 ndarray arr为:\n{arr}")
print(f"where 输出ndarray arr满足条件的下标为:\n{np.where(arr>5)}")
运行结果:
创建的随机数 ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
where 输出ndarray arr满足条件的下标为:
(array([0, 0, 1, 2, 2, 3, 3], dtype=int64), array([0, 2, 1, 0, 1, 1, 2], dtype=int64))
上述结果组合在一起有(0, 0),(0,2),(1,1)...
import numpy as np
np.random.seed(42) # 设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
arr1 = np.random.randint(-10, 1, size=12).reshape(4, 3)
print(f"创建的随机数 ndarray arr为:\n{arr}")
print(f"创建的随机数 ndarray arr1为:\n{arr1}")
# 若arr大于5,则保持arr对应位置,否则保留arr1对应位置
print(f"where 搜索符合条件的结果:\n{np.where(arr>5, arr,arr1)}")
运行结果:
创建的随机数 ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
创建的随机数 ndarray arr1为:
[[ -8 -5 -6]
[ -9 -3 -5]
[ -9 -6 -10]
[ -1 -5 -2]]
where 搜索符合条件的结果:
[[ 7 -5 8]
[ -9 7 -5]
[ 7 8 -10]
[ -1 8 8]]
extract 函数返回输入ndarray中满足给定条件的元素。
numpy.extract(条件,数组):如果满足某些指定条件,则返回input_array的元素。
import numpy as np
np.random.seed(42) # 设置随机种子
arr = np.random.randint(1, 10, size=12).reshape(4, 3)
print(f"创建的随机数 ndarray arr为:\n{arr}")
print(f"extract 搜索符合条件的结果:\n{np.extract(arr>5, arr)}")
运行结果:
创建的随机数 ndarray arr为:
[[7 4 8]
[5 7 3]
[7 8 5]
[4 8 8]]
extract 搜索符合条件的结果:
[7 8 7 7 8 8 8]
2.2.7字符串操作
对上述表中部分函数进行用法展示
import numpy as np
print(f"各字符串元素对应连接:{np.char.add(['hello', 'world'], ['xuan', 'haha'])}")
print(f"多重重复连接:{np.char.multiply(['hello', 'world'], 3)}")
print(f"拆分单个字符,以连接符连接:{np.char.join([':', '-'], ['hello', 'world'])}")
print(f"去除各个字符元素指定符号:{np.char.lstrip( ['helloh', 'hhworld'], 'h')}")
print(f"使用指定字符替换特定字符:{np.char.replace( ['hello, i am bob', 'good damam jin'], 'am', 'was')}")
运行结果
各字符串元素对应连接:['helloxuan' 'worldhaha']
多重重复连接:['hellohellohello' 'worldworldworld']
拆分单个字符,以连接符连接:['h:e:l:l:o' 'w-o-r-l-d']
去除各个字符元素指定符号:['elloh' 'world']
使用指定字符替换特定字符:['hello, i was bob' 'good dwaswas jin']
字符串查询函数
import numpy as np
arr = np.array(['aAaAaA', 'aa', 'aBAba1'])
print(f"字符A第一次出现的下标:{np.char.find(arr, 'A')}")
print(f"arr 元素的字符串是否由纯粹的字母组成:{np.char.isalpha(arr)}")
print(f"arr 中元素字母A出现的次数:{np.char.count(arr, 'A')}")
print(f"arr 中元素是否以a开头:{np.char.startswith(arr, 'a')}")
运行结果:
字符A第一次出现的下标:[ 1 -1 2]
arr 元素的字符串是否由纯粹的字母组成:[ True True False]
arr 中元素字母A出现的次数:[3 0 1]
arr 中元素是否以a开头:[ True True True]
2、ufunc
2.1 广播机制
广播机制,需要遵循4个原则:
1)让所有输入 ndarray 的 shape 最长的 ndarray 看齐, shape 中不足的部分都通过在前面加 1 补齐。
2)输出 ndarray 的 shape 是输入 ndarray shape 的各个轴上的最大值。
3)输入 ndarray 的某个轴和输出 ndarray 的对应轴的长度相同或其长度为1 时,这个 ndarray 能够用于计算,否则出错。
4) 当输入 ndarray 的某个轴的长度为1 ,且沿着此轴运算时,都用此轴上的第一组值。
一维 ndarray 的广播机制
import numpy as np
arr = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]])
print(f"创建的 ndarray arr 为: \n{arr}")
arr1 = np.array([1, 2, 3])
print(f"创建的 ndarray arr1 为: \n{arr1}")
print(f"arr 和 arr1 相加的结果 为: \n{arr + arr1}")
运行结果:
创建的 ndarray arr 为:
[[0 0 0]
[1 1 1]
[2 2 2]]
创建的 ndarray arr1 为:
[1 2 3]
arr 和 arr1 相加的结果 为:
[[1 2 3]
[2 3 4]
[3 4 5]]
二维ndarray 的广播机制
import numpy as np
arr = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [4, 4, 4]])
print(f"创建的 ndarray arr 为: \n{arr}")
arr1 = np.arange(1, 5).reshape(4, 1)
print(f"创建的 ndarray arr1 为: \n{arr1}")
print(f"arr 和 arr1 相加的结果 为: \n{arr + arr1}")
运行结果:
创建的 ndarray arr 为:
[[0 0 0]
[1 1 1]
[2 2 2]
[4 4 4]]
创建的 ndarray arr1 为:
[[1]
[2]
[3]
[4]]
arr 和 arr1 相加的结果 为:
[[1 1 1]
[3 3 3]
[5 5 5]
[8 8 8]]
2.2 常用运算
2.2.1 算术运算
NumPy 算术函数包含简单的加减乘除: add(),subtract(),multiply() 和 divide(),也包含常见的numpy.reciprocal(),numpy.power(),numpy.mod()。
需要注意的是数组必须具有相同的形状或符合数组广播规则。
import numpy as np
a = np.arange(9, dtype = np.float_).reshape(3,3)
print ('第一个数组:')
print (a)
print ('第二个数组:')
b = np.array([10,10,10])
print (b)
print ('两个数组相加:')
print (np.add(a,b))
print ('两个数组相减:')
print (np.subtract(a,b))
print ('两个数组相乘:')
print (np.multiply(a,b))
print ('两个数组相除:')
print (np.divide(a,b))
运行结果:
第一个数组:
[[0 1 2]
[3 4 5]
[6 7 8]]
第二个数组:
[10 10 10]
两个数组相加:
[[10 11 12]
[13 14 15]
[16 17 18]]
两个数组相减:
[[-10 -9 -8]
[ -7 -6 -5]
[ -4 -3 -2]]
两个数组相乘:
[[ 0 10 20]
[30 40 50]
[60 70 80]]
两个数组相除:
[[0. 0.1 0.2]
[0.3 0.4 0.5]
[0.6 0.7 0.8]]
numpy.reciprocal()
函数返回参数逐元素的倒数。如 1/4 倒数为 4/1。
import numpy as np
a = np.array([0.25, 1.33, 1, 100])
print('我们的数组是:')
print(a)
print('调用 reciprocal 函数:')
print(np.reciprocal(a))
运行结果:
我们的数组是:
[ 0.25 1.33 1. 100. ]
调用 reciprocal 函数:
[4. 0.7518797 1. 0.01 ]
numpy.power()
函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。
import numpy as np
a = np.array([10, 100, 1000])
print('我们的数组是;')
print(a)
print('调用 power 函数:')
print(np.power(a, 2))
print('第二个数组:')
b = np.array([1, 2, 3])
print(b)
print('再次调用 power 函数:')
print(np.power(a, b))
运行结果:
我们的数组是;
[ 10 100 1000]
调用 power 函数:
[ 100 10000 1000000]
第二个数组:
[1 2 3]
再次调用 power 函数:
[ 10 10000 1000000000]
numpy.mod()
计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。
import numpy as np
a = np.array([10, 20, 30])
b = np.array([3, 5, 7])
print('第一个数组:')
print(a)
print('第二个数组:')
print(b)
print('调用 mod() 函数:')
print(np.mod(a, b))
print('调用 remainder() 函数:')
print(np.remainder(a, b))
运算结果:
D:\APP\Anaconda\anaconda3\python.exe D:/exercise/python/test0/main.py
第一个数组:
[10 20 30]
第二个数组:
[3 5 7]
调用 mod() 函数:
[1 0 2]
调用 remainder() 函数:
[1 0 2]
2.2.2 三角函数
NumPy 提供了标准的三角函数:sin()、cos()、tan()等
import numpy as np
a = np.array([0, 30, 45, 60, 90])
print('不同角度的正弦值:')
# 通过乘 pi/180 转化为弧度
print(np.sin(a * np.pi / 180))
print('数组中角度的余弦值:')
print(np.cos(a * np.pi / 180))
print('数组中角度的正切值:')
print(np.tan(a * np.pi / 180))
运行结果:
不同角度的正弦值:
[0. 0.5 0.70710678 0.8660254 1. ]
数组中角度的余弦值:
[1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
6.12323400e-17]
数组中角度的正切值:
[0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
1.63312394e+16]
arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数。
这些函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。
import numpy as np
a = np.array([0, 30, 45, 60, 90])
print('含有正弦值的数组:')
sin = np.sin(a*np.pi/180)
print(sin)
print('计算角度的反正弦,返回值以弧度为单位:')
inv = np.arcsin(sin)
print(inv)
print('通过转化为角度制来检查结果:')
print(np.degrees(inv))
print('arccos 和 arctan 函数行为类似:')
cos = np.cos(a*np.pi/180)
print(cos)
print('反余弦:')
inv = np.arccos(cos)
print(inv)
print('角度制单位:')
print(np.degrees(inv))
print('tan 函数:')
tan = np.tan(a*np.pi/180)
print(tan)
print('反正切:')
inv = np.arctan(tan)
print(inv)
print('角度制单位:')
print(np.degrees(inv))
运行结果:
含有正弦值的数组:
[0. 0.5 0.70710678 0.8660254 1. ]
计算角度的反正弦,返回值以弧度为单位:
[0. 0.52359878 0.78539816 1.04719755 1.57079633]
通过转化为角度制来检查结果:
[ 0. 30. 45. 60. 90.]
arccos 和 arctan 函数行为类似:
[1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
6.12323400e-17]
反余弦:
[0. 0.52359878 0.78539816 1.04719755 1.57079633]
角度制单位:
[ 0. 30. 45. 60. 90.]
tan 函数:
[0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
1.63312394e+16]
反正切:
[0. 0.52359878 0.78539816 1.04719755 1.57079633]
角度制单位:
[ 0. 30. 45. 60. 90.]
2.2.3集合运算
import numpy as np
arr = np.arange(-4, 5)
print(f"创建的 ndarray arr 为:{arr}")
arr1 = np.arange(9)
print(f"创建的 ndarray arr1 为:{arr1}")
print(f" ndarray arr1 和 arr的交集为:{np.intersect1d(arr, arr1)}")
print(f" ndarray arr1 和 arr的并集为:{np.union1d(arr, arr1)}")
print(f" ndarray arr1 和 arr的差集为:{np.setdiff1d(arr, arr1)}")
print(f" ndarray arr1 和 arr的对称差集为:{np.setxor1d(arr, arr1)}")
运行结果:
创建的 ndarray arr 为:[-4 -3 -2 -1 0 1 2 3 4]
创建的 ndarray arr1 为:[0 1 2 3 4 5 6 7 8]
ndarray arr1 和 arr的交集为:[0 1 2 3 4]
ndarray arr1 和 arr的并集为:[-4 -3 -2 -1 0 1 2 3 4 5 6 7 8]
ndarray arr1 和 arr的差集为:[-4 -3 -2 -1]
ndarray arr1 和 arr的对称差集为:[-4 -3 -2 -1 5 6 7 8]
2.2.4比较运算
2.2.5逻辑运算
2.2.6统计计算
部分函数使用展示如下:
numpy.min() 和 numpy.max()
import numpy as np
a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print('我们的数组是:')
print(a)
print('调用 min() 函数:')
print(np.min(a, 1))
print('再次调用 min() 函数:')
print(np.min(a, 0))
print('调用 max() 函数:')
print(np.max(a))
print('再次调用 max() 函数:')
print(np.max(a, axis = 0))
运行结果:
我们的数组是:
[[3 7 5]
[8 4 3]
[2 4 9]]
调用 min() 函数:
[3 3 2]
再次调用 min() 函数:
[2 4 3]
调用 max() 函数:
9
再次调用 max() 函数:
[8 7 9]
numpy.ptp()函数计算数组中元素最大值与最小值的差(最大值 – 最小值)。
import numpy as np
a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print('我们的数组是:')
print(a)
print('调用 ptp() 函数:')
print(np.ptp(a))
print('沿轴 1 调用 ptp() 函数:')
print(np.ptp(a, axis=1))
print('沿轴 0 调用 ptp() 函数:')
print(np.ptp(a, axis=0))
运行结果:
我们的数组是:
[[3 7 5]
[8 4 3]
[2 4 9]]
调用 ptp() 函数:
7
沿轴 1 调用 ptp() 函数:
[4 5 7]
沿轴 0 调用 ptp() 函数:
[6 3 6]
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)
import numpy as np
a = np.array([[30, 65, 70], [80, 95, 10], [50, 90, 60]])
print('我们的数组是:')
print(a)
print('调用 median() 函数:')
print(np.median(a))
print('沿轴 0 调用 median() 函数:')
print(np.median(a, axis=0))
print('沿轴 1 调用 median() 函数:')
print(np.median(a, axis=1))
运行结果:
我们的数组是:
[[30 65 70]
[80 95 10]
[50 90 60]]
调用 median() 函数:
65.0
沿轴 0 调用 median() 函数:
[50. 90. 60.]
沿轴 1 调用 median() 函数:
[65. 80. 60.]
方差与标准差
import numpy as np
a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print(f"原始数组为:\n{a}")
print(f"原始数组标准差为:\n{np.std(a)}")
print(f"原始数组方差为:\n{np.var(a)}")
运行结果:
原始数组为:
[[3 7 5]
[8 4 3]
[2 4 9]]
原始数组标准差为:
2.309401076758503
原始数组方差为:
5.333333333333333
加权平均
import numpy as np
# a同学和b同学成绩谁更好
a = np.array([85, 90, 79])
b = np.array([82, 96, 83])
# 权重
weight = np.array([0.2, 0.3, 0.5])
# 加权平均
print(f"a同学的加权平均值:{np.average(a,weights=weight)}")
print(f"b同学的加权平均值:{np.average(b,weights=weight)}")
运行结果:
a同学的加权平均值:83.5
b同学的加权平均值:86.7
3、 matrix 与 线性代数
NumPy 的 matrix 是继承自NumPy 的二维 ndarray 对象,不仅拥有二维ndarray 的属性、方法和函数,还拥有诸多特有的属性和方法。同时,NumPy 中的 matrix 与线性代数中的矩阵概念几乎完全相同,同样含有转置矩阵、共轭矩阵、逆矩阵等概念。
3.1创建NumPy矩阵
NumPy 中可以使用 mat、matrix 或bmat函数来创建矩阵。使用 mat 函数创建矩阵时,若输入matrix 或 ndarray 对象,则不会为他们创建副本。因此,调用 mat 函数与调用 matrix(data,copy=False)等价,代码如下:
import numpy as np
mat1 = np.mat("1, 2, 3; 4, 5, 6; 7, 8, 9")
print(f"创建的矩阵 mat1 为:\n{mat1}")
mat2 = np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"创建的矩阵 mat2 为:\n{mat2}")
运行结果:
创建的矩阵 mat1 为:
[[1 2 3]
[4 5 6]
[7 8 9]]
创建的矩阵 mat2 为:
[[1 2 3]
[4 5 6]
[7 8 9]]
将小矩阵组合成大矩阵是一种使用频率极高的操作。在NumPy中可以使用 bmat 分块矩阵(Block Matrix)函数实现。代码如下:
import numpy as np
arr1 = np.eye(3)
print(f"创建的 ndarray arr1为:\n{arr1}")
arr2 = 3 * arr1
print(f"创建的 ndarray arr2为:\n{arr2}")
mat = np.bmat('arr1 arr2; arr1 arr2')
print(f"创建的矩阵为:\n{mat}")
运行结果:
创建的 ndarray arr1为:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
创建的 ndarray arr2为:
[[3. 0. 0.]
[0. 3. 0.]
[0. 0. 3.]]
创建的矩阵为:
[[1. 0. 0. 3. 0. 0.]
[0. 1. 0. 0. 3. 0.]
[0. 0. 1. 0. 0. 3.]
[1. 0. 0. 3. 0. 0.]
[0. 1. 0. 0. 3. 0.]
[0. 0. 1. 0. 0. 3.]]
3.2矩阵的属性和基本运算
属性 | 说明 |
T | 返回自身的转置 |
H | 返回自身的共轭转置 |
I | 返回自身的逆转置 |
import numpy as np
mat = np.matrix(np.arange(4).reshape(2, 2))
print(f"矩阵 mat转置矩阵为:\n{mat.T}")
print(f"矩阵共轭转置矩阵为:\n{mat.H}")
print(f"矩阵 mat 的逆矩阵为:\n{mat.H}")
运行结果:
矩阵 mat转置矩阵为:
[[0 2]
[1 3]]
矩阵共轭转置矩阵为:
[[0 2]
[1 3]]
矩阵 mat 的逆矩阵为:
[[0 2]
[1 3]]
在 NumPy中,矩阵运算与 ndarray 类似,都能作用于每个元素。
import numpy as np
mat1 = np.mat("1, 2, 3; 4, 5, 6; 7, 8, 9")
print(f"创建的矩阵 mat1 为:\n{mat1}")
mat2 = np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"创建的矩阵 mat2 为:\n{mat2}")
print(f"矩阵 mat1和 mat2 相加结果为:\n{mat1 + mat2}")
print(f"矩阵 mat1和 mat2 相减结果为:\n{mat1 - mat2}")
print(f"矩阵 mat1和 mat2 相乘结果为:\n{mat1 * mat2}")
print(f"矩阵 mat1和 mat2 点乘结果为:\n{np.multiply(mat2, mat1)}")
运行结果:
创建的矩阵 mat1 为:
[[1 2 3]
[4 5 6]
[7 8 9]]
创建的矩阵 mat2 为:
[[1 2 3]
[4 5 6]
[7 8 9]]
矩阵 mat1和 mat2 相加结果为:
[[ 2 4 6]
[ 8 10 12]
[14 16 18]]
矩阵 mat1和 mat2 相减结果为:
[[0 0 0]
[0 0 0]
[0 0 0]]
矩阵 mat1和 mat2 相乘结果为:
[[ 30 36 42]
[ 66 81 96]
[102 126 150]]
矩阵 mat1和 mat2 点乘结果为:
[[ 1 4 9]
[16 25 36]
[49 64 81]]