Numpy

Numpy科学计算库跟高数和线性代数还有概率论与数理统计的一些内容紧密相关,高数也是工科理科考研的必备科目之一,学好数学对与学习这些科学库有很大的帮助的说,比较重要的都加了⭐️。

可以看看公共基础知识:https://liamjohnson-w.github.io/2025/06/04/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%9F%BA%E7%A1%80/#%E9%99%84%E4%BB%B6

⭐️⭐️Numpy属性

ndarray对象属性有:

  • ndarray.ndim
  • ndarray.shape
  • ndarray.size
  • ndarray.dtype
  • ndarray.itemsize

代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np

a = np.arange(15).reshape(3, 5)

print("数组的维度:", a.shape)
# 输出: 数组的维度: (3, 5)

print("数组轴的个数:", a.ndim) #就是维度 2维矩阵
# 输出: 数组轴的个数: 2

print("数组元素类型:", a.dtype)
# 输出: 数组元素类型: int64

print("数组中每个元素的字节大小:", a.itemsize)
# 输出: 数组中每个元素的字节大小: 8

print("数组元素的总个数:", a.size)
# 输出: 数组元素的总个数: 15

print("类型查询:", type(a))
# 输出: 类型查询: <class 'numpy.ndarray'>

# 创建一个数组
b = np.array([6, 7, 8])

print("数组b:", b)
# 输出: 数组b: [6 7 8]

print("数组b类型:", type(b))
# 输出: 数组b类型: <class 'numpy.ndarray'>

⭐️⭐️⭐️创建Ndarray

序列创建

创建等差序列数组:np.arange(start, stop, step)

然后通过np.arange.reshape(3, 2)创建一个3行2列的矩阵

1
2
np.arange(5)       # [0,1,2,3,4]
np.arange(1,10,2) # [1,3,5,7,9]

随机创建

方法 功能 示例
np.random.rand() [0,1)均匀分布 np.random.rand(2,3) → 2×3均匀分布矩阵
np.random.randint() 指定范围随机整数 np.random.randint(1,10,size=(3,3))
np.random.uniform() 指定范围均匀分布 np.random.uniform(5.0,10.0,size=5)
np.random.randn() 标准正态分布 np.random.randn(100) → 100个标准正态样本

等差等比数列

  • 等差数列:np.linspace(start, stop, num=50)
1
np.linspace(0, 10, 5)  # [0.0, 2.5, 5.0, 7.5, 10.0]
  • 等比数列:np.logspace(start, stop, num=50, base=10)
1
np.logspace(0, 2, 3)  # [1.0, 10.0, 100.0]

⭐️基本函数

  • np.ceil(): 向上最接近的整数,参数是 number 或 array
  • np.floor(): 向下最接近的整数,参数是 number 或 array
  • np.rint(): 四舍五入,参数是 number 或 array
  • np.isnan(): 判断元素是否为 NaN(Not a Number),参数是 number 或 array
  • np.multiply(): 元素相乘,参数是 number 或 array
  • np.divide(): 元素相除,参数是 number 或 array
  • np.abs():元素的绝对值,参数是 number 或 array
  • np.where(condition, x, y): 三元运算符,x if condition else y

代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import numpy as np

# 生成2x3的标准正态分布随机数组
arr = np.random.randn(2, 3)

print("原始数组:")
print(arr)
"""
原始数组:
[[ 0.123, -1.456, 0.789]
[-0.987, 1.234, -0.567]]
"""

print("\n向上取整(ceil):")
print(np.ceil(arr))
"""
向上取整(ceil):
[[ 1., -1., 1.]
[-0., 2., -0.]]
"""

print("\n向下取整(floor):")
print(np.floor(arr))
"""
向下取整(floor):
[[ 0., -2., 0.]
[-1., 1., -1.]]
"""

print("\n判断是否为NaN:")
print(np.isnan(arr))
"""
判断是否为NaN:
[[False False False]
[False False False]]
"""

print("\n元素相乘:")
print(np.multiply(arr, arr))
"""
元素相乘:
[[0.015, 2.120, 0.623]
[0.974, 1.523, 0.321]]
"""

print("\n元素相除:")
print(np.divide(arr, arr))
"""
元素相除:
[[ 1., 1., 1.]
[ 1., 1., 1.]]
"""

print("\n条件赋值(where):")
print(np.where(arr > 0, 1, -1))
"""
条件赋值(where):
[[ 1, -1, 1]
[-1, 1, -1]]
"""

各操作详细解释

  1. 原始数组生成
    • np.random.randn(2,3) 生成2行3列的数组,元素来自标准正态分布(均值0,标准差1)
    • 示例值包含正负数,绝对值通常在0到2之间
  2. 向上取整(np.ceil)
    • 每个元素向正无穷方向取整
    • 例如:0.123 → 1,-1.456 → -1
  3. 向下取整(np.floor)
    • 每个元素向负无穷方向取整
    • 例如:0.789 → 0,-0.987 → -1
  4. NaN判断(np.isnan)
    • 检查每个元素是否为NaN(非数字)
    • 本例中所有元素都是有效数字,返回全False
  5. 元素相乘(np.multiply)
    • 数组与自身逐元素相乘(相当于平方)
    • 结果均为非负数
  6. 元素相除(np.divide)
    • 数组与自身逐元素相除
    • 任何非零数除以自身得1.0
    • 如果原数组有0,会产生inf或nan
  7. 条件赋值(np.where)
    • 元素大于0赋值为1,否则赋值为-1
    • 实现了一种二值化操作

注意

  1. 每次运行np.random.randn()会产生不同的随机数组
  2. 如果数组中恰好出现0,np.divide(arr, arr)会产生inf(除以零)
  3. 对于非常大的数组,这些操作都是向量化的,执行效率很高
  4. 在科学计算中,这些基础操作常被用于数据预处理和特征工程

⭐️统计函数

  • np.mean(), np.sum():所有元素的平均值,所有元素的和,参数是 number 或 array
  • np.max(), np.min():所有元素的最大值,所有元素的最小值,参数是 number 或 array
  • np.std(), np.var():所有元素的标准差,所有元素的方差,参数是 number 或 array
  • np.argmax(), np.argmin():最大值的下标索引值,最小值的下标索引值,参数是 number 或 array
  • np.cumsum(), np.cumprod():返回一个一维数组,每个元素都是之前所有元素的 累加和 和 累乘积,参数是 number 或 array 多维数组默认统计全部维度,axis参数可以按指定轴心统计,值为0则按列统计,值为1则按行统计。

代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import numpy as np

# 创建一个3x4的二维数组
arr = np.arange(12).reshape(3,4)

# 打印原始数组
print(arr)
# 输出示例:
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]

# 计算累积和
print(np.cumsum(arr))
# 输出示例:
# [ 0 1 3 6 10 15 21 28 36 45 55 66]
# 注释:返回一个一维数组,每个元素都是之前所有元素的累加和

# 计算所有元素的和
print(np.sum(arr))
# 输出示例:66
# 注释:所有元素的和

# 按列求和
print(np.sum(arr, axis=0))
# 输出示例:[12 15 18 21]
# 注释:数组的按列统计和

# 按行求和
print(np.sum(arr, axis=1))
# 输出示例:[ 6 22 38]
# 注释:数组的按行统计和

⭐️⭐️⭐️去重&排序函数

向量去重

1
2
3
4
5
import numpy as np

arr = np.array([3, 1, 2, 2, 3, 1, 4])
unique_arr = np.unique(arr)
print(unique_arr) # 输出: [1 2 3 4]
参数 说明 示例
return_index 返回唯一值在原数组的首次出现索引 np.unique(arr, return_index=True)
return_inverse 返回重建原数组所需的索引 np.unique(arr, return_inverse=True)
return_counts 返回每个唯一值的出现次数 np.unique(arr, return_counts=True)
axis 指定沿哪个轴操作 np.unique(arr_2d, axis=0)

矩阵去重

1
2
3
# 二维数组去重
arr_2d = np.array([[1,2], [3,4], [1,2]])
print(np.unique(arr_2d, axis=0)) # 输出: [[1 2] [3 4]]

排序

可以指定排序算法,默认为快排quicksort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 普通排序
arr = np.array([3, 1, 4, 2])
# np.sort()返回新数组
sorted_arr = np.sort(arr) # [1 2 3 4]
arr.sort() # arr变为[1 2 3 4]

# 按指定轴排序
arr_2d = np.array([[3,2], [1,4], [2,1]])
print(np.sort(arr_2d, axis=0))
"""
[[1 1]
[2 2]
[3 4]]
"""

# 结构化数组排序
dt = np.dtype([('name', 'S10'), ('age', int)])
people = np.array([('Alice', 25), ('Bob', 19), ('Charlie', 30)], dtype=dt)
print(np.sort(people, order='age'))
# 输出: [(b'Bob', 19) (b'Alice', 25) (b'Charlie', 30)]

参数

参数 说明 可选值
kind 排序算法 ‘quicksort’(默认), ‘mergesort’, ‘heapsort’, ‘stable’
axis 排序轴向 默认-1(最后轴)
order 结构化数组排序字段 字段名字符串

排序算法对比

算法 时间复杂度 稳定性 适用场景
quicksort O(n log n) 不稳定 通用场景(默认)
mergesort O(n log n) 稳定 需要稳定排序时
heapsort O(n log n) 不稳定 内存受限时
timsort O(n log n) 稳定 实际数据中有序子序列多时

⭐️⭐️⭐️矩阵操作

常规乘法操作

常规乘法也就是哈达玛积。

1
2
3
4
5
6
7
8
9
import numpy as np

# 创建两个相同的2x3数组
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[1, 2, 3], [4, 5, 6]])

# 两种方式进行数组元素相乘
print(a * b ) # 运算符方式
print(np.multiply(a, b) ) # 函数方式

两种乘法方式结果相同,都是对应元素相乘:

1
2
array([[ 1,  4,  9],
[16, 25, 36]])

⭐️⭐️⭐️点积

语法糖:arr1@arr2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np

x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[6, 23], [-1, 7], [8, 9]])

print(x)
# [[1 2 3]
# [4 5 6]]
print(y)
# [[ 6 23]
# [-1 7]
# [ 8 9]]

print(x.dot(y)) # 方式1:数组对象的dot方法
print(np.dot(x, y)) # 方式2:numpy模块的dot函数
# [[ 28 64]
# [ 67 181]]
# 点积也可以使用arr1@arr2

线性代数&概率论

Normal Distribution

正态分布是一种概率分布。正态分布是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的标准差,所以正态分布记作N(μ,σ )

image-20240805221036823

正态分布的特点(标准正态分布)

μ决定了其位置,其标准差σ决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布

方差&标准差

方差是在概率论和统计方差衡量一组数据时离散程度的度量,一般用σ^2^来表示

image-20240805221343696

Uniform Distribution

学概率论学明白的一种思想就是遇到任何一种类型的分布首先判断是离散型还是连续型。概率论中,离散型均匀分布是离散型概率分布,其中有限个数值拥有相同的概率。离散型均匀分布的另一种说法为“有限个结果,各结果的概率均相同”。

像均匀的骰子就是离散型均匀分布的例子,可能的值为1, 2, 3, 4, 5, 6,而每一个数字的概率都是1/6。但若同时丢二个均匀骰子,将其值相加,就不是离散型均匀分布了,因为各个和的概率不同。

下面还是着重弄搞连续性均匀分布

连续性均匀分布定义

均匀分布也叫矩形分布,它是对称概率分布,在相同长度间隔的分布概率是等可能的。

均匀分布由两个参数a和b定义,它们是数轴上的最小值和最大值,通常缩写为U(a,b)。

概率密度函数

image-20240805223735824

在均匀分布中,概率密度函数(PDF)在整个区间 [a, b] 上是恒定的,即对于任意 x 属于 [a, b],概率密度$\bigl(f(x)\bigr)$都等于 $\frac{1}{b-a}$。这意味着,任意一个小区间 [x, x+dx] 内随机变量取值的概率与 dx 成正比。

image-20240806080619295

行列式和矩阵

转置

行列式转置之前

$\begin{bmatrix} {a_{11}}&{a_{12}}&{\cdots}&{a_{1n}}\\ {a_{21}}&{a_{22}}&{\cdots}&{a_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{m1}}&{a_{m2}}&{\cdots}&{a_{mn}}\\ \end{bmatrix}$

矩阵转置之后

$\begin{bmatrix} {a_{11}}&{a_{21}}&{\cdots}&{a_{m1}}\\ {a_{12}}&{a_{22}}&{\cdots}&{a_{m2}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{1n}}&{a_{2n}}&{\cdots}&{a_{nm}}\\ \end{bmatrix}$

Numpy

Numpy是什么:

  • Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度的数组
  • Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用Numpy比直接使用Python要简洁的多。
  • Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器。

NumPy provides an N-dimensional array type, the ndarray, which describes a collection of “items” of the same type.

Numpy优势

  • NumPy提供了一个N维数组类型ndarray,它描述了相同类型的“items”的集合。
    • Numpy专门针对ndarray的操作和运算进行了设计,所以数组的存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,Numpy的优势就越明显。
  • 支持并行化运算
    • numpy内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy会自动做并行计算(向量化运算)。
  • 效率远高于纯Python代码
    • Numpy底层使用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,所以,其效率远高于纯Python代码。

numpy内存地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import random
import time
import numpy as np

a = []
for i in range(100000000):
# 生成巨多个随机数加入到Python的原生list列表里面
a.append(random.random())

# 通过%time 魔法方法,查看当前行的代码运行一次所花费的时间
%time sum1 = sum(a)

b = np.array(a)

%time sum2 = np.sum(b)
1
2
3
4
CPU times: total: 594 ms
Wall time: 619 ms
CPU times: total: 188 ms
Wall time: 187 ms

ndarray的属性

数组属性反映了数组本身固有的信息,需要深入学习的就是ndarray的形状和类型。

属性名字 属性解释
ndarray.shape 数组维度的元组
ndarray.ndim 数组维数
ndarray.size 数组中的元素数量
ndarray.itemsize 一个数组元素的长度(字节)
ndarray.dtype 数组元素的类型
1
2
3
4
5
6
7
8
9
# 创建不同形状的数组
import numpy as np
a = np.array([[1,2,3],
[4,5,6]])
print(a.shape) # 二维数组(2, 3)
b = np.array([1234])
print(b.shape) # 一维数组(1,)
c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]])
print(c.shape) # 三维数组(2, 2, 3) 我的理解 2个二维数组,二维数组是两行三列的

ndarray的类型

通过ndarray.dtype这个函数来获取咱们多维数组的类型。

1
2
3
4
5
6
7
8
9
import numpy as np
a = np.array([[1,2,3],[4,5,6]], dtype=np.float32)
print(a.dtype) # 获取到咱们指定的类型float32

arr = np.array(['python','tensorflow','scikit-learn','numpy'], dtype = np.string_)
print(arr.dtype) # 设置数组类型为np的string类型(输出|S12)

c = np.array([b'python',b'tensorflow', b'scikit-learn',b'numpy'],dtype='|S12')
print(c.dtype) # 设置数组类型为 dtype 的|S12类型 和arr的类型相同

Numpy生成数组

生成0和1的数组

  • np.ones(shape, dtype)
    • 生成一组1、形状和类型可以指定
  • np.ones_like(a, dtype)
    • 给定一个已知的数组,生成一个类型相同的数组,只有类型可以指定
  • np.zeros(shape, dtype)
    • 生成一组0、形状和类型可以指定
  • np.zeros_like(a, dtype)
    • 给定一个已知的数组,生成一个类型相同的数组,只有类型可以指定
1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np

ones = np.ones([4,8])
# [[1. 1. 1. 1. 1. 1. 1. 1.]
# [1. 1. 1. 1. 1. 1. 1. 1.]
# [1. 1. 1. 1. 1. 1. 1. 1.]
# [1. 1. 1. 1. 1. 1. 1. 1.]]
zero = np.zeros_like(ones)
# [[0. 0. 0. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 0. 0. 0.]]

通过现有数组生成数组

  • np.array(object, dtype)
    • object是一个已知的数组,通常会自己写一个,dtype是指定类型
  • np.asarray(a, dtype)
    • 相当于创建了一个索引,引用的还是a数组(之前的数组)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
# 通过现有数组生成
# np.array(object, dtype)
# np.asarray(a, dtype)
a = np.array([[1,2,3],[4,5,6]])
# 从现有的数组当中创建
a1 = np.array(a)

# 相当于索引的形式, 并没有真正的创建一个新的(浅拷贝)
a2 = np.asarray(a)
# 修改a数组中的第一行第一列的值为100
a[0,0] = 100
print(a)
print(a1)
print(a2)

输出的结果为:

1
2
3
4
5
6
7
8
>[[100   2   3]
[ 4 5 6]]

>[[1 2 3]
[4 5 6]]

>[[100 2 3]
[ 4 5 6]]

生成指定范围的数组(等差、等比数列)

  • 创建等差数列:np.linspace(start, stop, num, endpoint)
    • 起始位置, 结束位置, 等差数列的数量, endpoint:序列中是否包含stop值,默认为ture
  • 创建等差数组并指定步长: np.arange(start,stop, step, dtype)
    • 其实就是类似于for i in range(10), 然后生成step 步长默认为1
  • 创建等比数列: np.logspace(start, stop, num)
    • 起始位置, 结束位置, 生成等比数列的数量
1
2
3
4
5
6
7
print(np.linspace(0,100,11))  # [  0.  10.  20.  30.  40.  50.  60.  70.  80.  90. 100.] # # 等差数列是否指定数量, 是否包含结尾的数据

print(np.arange(10, 50, 2)) # [10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48]
# 等差数列指定步长

print(np.logspace(0, 2, 3))
# 创建等比数列,num为要生成等比数列的个数, 如果不指定则默认为50

随机生成数组(正态分布,均匀分布)

  • 正态分布相关函数:

    • np.random.randn(d0, d1, …., dn) 从标准正态分布中返回一个活多个样本值
      • 标准正态分布μ=0,θ^2^=1(上面的数学部分有画图)
    • np.random.normal(loc=0.0, scale=1.0, size=None) 返回指定形态的正态分布
    • np.random.standard_normal(size=None) 返回指定形状的标准正态分布数组
  • 均匀分布相关函数:

    • np.random.rand(d0, d1, , dn) 返回**[0.0,1.0)**内的一组均匀分布的数。
    • np.random.uniform(low=0.0, high=1.0, size=None) 从一个均匀分布[low,high)中随机采样,注意定义域是左闭右开,即包含low,不包含high.
    • np.random.randint(low, high=None, size=None, dtype=’l’) 从一个均匀分布中随机采样,生成一个整数或N维整数数组,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
import matplotlib.pyplot as plt

# 生成均值为1.75,标准差为1的正态分布数据,100000000个 (均值是μ,标准差是δ) 谬 德尔塔 搜狗输入法会显示
x1 = np.random.normal(1.75, 1, 10000000)
# 生成标准正态分布(μ=0,δ=1)
x1 = np.random.standard_normal(100000000)
#
# 创建画布
plt.figure(figsize=(20,10), dpi=100)

# 绘制直方图
plt.hist(x1, 1000)

# 显示图像
plt.show()

image-20240812161513717

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

# 均匀分布是关于定义在区间[a,b], (a<b)上连续变量的简单概率分布
# np.random.rand(*d0, *d1, *.....*, *dn*) 返回[0.0, 1.0) 内的一组均匀分布的数
# np.random.uniform(*low=0.0*, *high=1.0*, *size=None*) 从一个均匀分布[0,1)中随机采样, 左闭右开区间 size为输出样本数目
# matplotlib 结合numpy生成均匀分布直方图
x2 = np.random.uniform(-1, 1, 1000000)

# 创建画布
plt.figure(figsize=(10, 10), dpi=80)

# 绘制直方图
plt.hist(x=x2, bins=1000) # x代表要使用的数据, bins表示哟啊划分的区间数

# 显示图像
plt.show()

image-20240812161647651

数组的索引、切片

  • a = np.array([[[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
    • a[0,0,1]:获取其中的元素2(三维数组中的第1个二维数组,二维数组的第一个1维数组,第一个一维数组中的第二个元素)
  • stock_change = np.random.normal(0, 1, (4, 5))
    • stock_change[0, :3] :获取第一支股票前三个交易日的涨跌幅数据
1
2
3
4
5
6
7
8
9
10
11
12
13
# 案例:随机生成4支股票一周的交易日涨幅数据
# 创建符合正态分布的4只股票5天的涨跌幅数据
stock_change = np.random.normal(0, 1, (4, 5))
print(stock_change)

# 获取第一支股票前三个交易日的涨跌幅数据
stock_change[0, :3] # 二维数组的索引方式

# 三维数组的索引方式
a1 = np.array([ [[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
print(a1)
# 获取其中的元素2(三维数组中的第1个二维数组,二维数组的第一个1维数组,第一个一维数组中的第二个元素)
a1[0,0,1]

数组形状修改、类型修改、数组的去重

  • ndarray.reshape(shape,order)
    • 返回一个具有相同数据域,但shape不一样的视图(行、列不进行互换
  • ndarray.resize(new_shape)
    • 修改数组本身的形状(需要保持元素个数前后相同)行、列不进行互换
  • ndarray.T:数组的转置:将数组的行、列进行互换
  • np.unique(ndarray): 对ndarray数组进行去重
    • 注意:如果ndarray是二维数组的话,且单纯的输出上述去重的数据那么去重后的结果就是列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import numpy as np
# 形状修改
# ndarray.reshape(shape, order)
# 返回一个具有相同数据域,但shape不一样的视图
# 行、列不进行互换
# ndarray.resize(new_shape)
# 修改数组本身的形状(需要保持元素个数前后相同)
# 行、列不进行互换
# ndarray.T
# 数组的转置
# 将数组的行、列进行互换
arr = np.array([[1, 2, 3], [4, 5, 6]]) # 两行三列
# arr.reshape([3,2]) # 将arr数组变为指定行列的数组
# [[1 2]
# [3 4]
# [5 6]]

# arr.resize([3,2])
# [[1, 2],
# [3, 4],
# [5, 6]]

arr.T
# [[1, 2],
# [3, 4],
# [5, 6]]


# 类型修改
# ndarray.tostring()
# 构造包含数组中原始数据字节的Python字节
# ndarray.astype()
# 返回修改了类型之后的数组
print(arr.dtype) # 之前的类型int32
arr.astype(np.int64)
print(arr.astype(np.int64).dtype) # astype()会返回修改了类型之后的数组,之前数组的类型不会改变

# 数组构造:构造包含数组中原始数据字节的Python字节
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
arr.tostring()

# 数组的去重 :通过np.unique()可以实现数组去重的目的
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]])
print(np.unique(temp)) # [1 2 3 4 5 6]

Numpy运算

逻辑运算

  • ndarray > Integer:直接写判断逻辑,就会将ndarray中满足条件的数据标记为True,不满足的标记为False
  • ndarray[ndarray > Integer] = 1:将判断逻辑写在ndarray数组中,将符合条件的标记为指定的数据1.
  • np.all(ndarray[切片] > Integer):判断ndarray数组的切片是否全部满足逻辑
  • np.any(ndarray[切片] > Integer):判断ndarray数组的切片是否存在部分满足逻辑的,标记为True||False
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np

# 随机生成10位同学的5门课成绩,随机数在40,到100 之间
score = np.random.randint(40, 100, (10,5))

# 取出最后4名同学的成绩,用于逻辑判断
test_score = score[6:, 0:5]

# 逻辑判断,如果成绩大于60就标记位True,否则就为False
test_score > 60
"""
array([[ True, False, True, True, True],
[ True, True, True, True, True],
[False, True, True, True, True],
[ True, True, True, True, True]])
"""

# bool 赋值, 将满足条件的设置为指定的值 布尔索引
test_score[test_score > 60] = 1
test_score
"""
array([[46, 59, 1, 1, 46],
[44, 40, 1, 46, 1],
[50, 1, 56, 57, 1],
[49, 1, 1, 1, 1]])
"""

# np.all()
# 判断前两名同学的成绩[0:2, :] 是否全部及格
# np.all(score[0:2, :] > 60) # False

# np.any()
# 判断前两名同学的成绩[0:2, :]是否有大于90分的
np.any(score[0:2, :] > 70) # True

统计运算

几个常见的numpy的统计指标的方法,其实都是有很多共性的,比如说都是np的方法,需要使用np.的方式调用。

下面没有写全:numpy.var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False)

1
2
3
4
5
6
a: 输入数组。
axis: 指定沿哪个轴计算方差。如果是 None(默认值),则计算整个数组的方差;如果是整数,则沿指定的轴计算方差。
dtype: 可选参数,指定计算方差时使用的数据类型。如果未指定,则默认使用输入数组的类型。
out: 可选参数,用于存储结果的数组。如果未指定,结果将以新的数组返回。
ddof: “自由度调整”参数。默认值为 0。通常在计算样本方差时设置为 1,以便进行无偏估计。
keepdims: 如果设置为 True,则保持轴的维度,即结果数组与输入数组的维度相同,除非指定的轴被压缩。
  • np.min(ndarray,axis):求最小值
    • 注意这里的numpy数组是ndarray-numpy的数据类型,后面学到一个科学库,首先就是弄清楚这个科学库的最基本的东西,比如数据类型,数据类型的分类。
  • np.max(ndarray,axis):求最大值
  • np.mean(ndarray,axis):求平均值
  • np.std(ndarray,axis):求标准差(能够反映数据的波动情况
  • np.var(ndarray,axis):求方差
    • var =variance(方差的缩写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# min(a, axis)
# Return the minimum of an array or minimum along an axis.
# max(a, axis])
# Return the maximum of an array or maximum along an axis.
# median(a, axis)
# Compute the median along the specified axis.
# mean(a, axis, dtype)
# Compute the arithmetic mean along the specified axis.
# std(a, axis, dtype)
# Compute the standard deviation along the specified axis.
# var(a, axis, dtype)
# Compute the variance along the specified axis.

# 案例:学生成绩统计运算 axis 0代表列, axis 1
tmp = score[:4, :5]
print(tmp)
print("前四名学生中,各科成绩的最大分数:{}".format(np.max(tmp, axis=0))) # 统计每一列的最大值
print("前四名学生中,各科成绩的最小分:{}".format(np.min(tmp, axis=0))) # 统计每一列的最小值
print("前四名学生中,各科成绩波动情况:{}".format(np.std(tmp, axis=0)))
print("前四名学生中,各科成绩的平均分:{}".format(np.mean(tmp, axis=0)))

# 统计某科成绩最高分和最低分
print("前四名学生,各科成绩最高分对应的学生下标:{}".format(np.argmax(tmp, axis=0)))
print("前四名学生,各科成绩最低分对应的学生下标:{}".format(np.argmin(tmp, axis=0)))

数组的运算

矩阵的加减乘除就是直接运算就行,剩下的都是剩下的。

1
2
3
4
5
6
7
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
arr + 1 # 对数组中的所有元素进行加1的操作
arr /2 # 对数组中的所有元素除以一个整数

# 可以对比python列表的运算,看出区别
a = [1, 2, 3, 4, 5]
a * 3 # [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] 相当于将列表元素复制了三份添加到了这个列表中

数组跟数组之间的运算,跟线代非常相似。

  • 相同形状的数组才能操作
  • 不同形状的数组需要前一个数组的列和后一个数组的行相同,也能通过广播机制进行操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np

# 跟线性代数中的一些特性非常的相似,只有形状相同的矩阵才能进行操作
arr1 = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])
arr2 = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])
arr1 + arr2

# 不同形状的二维数组不能进行操作,否则报错ValueError: operands could not be broadcast together with shapes (2,6) (2,4)
arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
arr2 = np.array([[1, 2, 3, 4], [3, 4, 5, 6]])
# arr1 + arr2 报错:ValueError: operands could not be broadcast together with shapes (2,6) (2,4)

# 不同维度的数组运算的广播机制判定条件(能够进行相加的条件)满足下面任意一个条件即可
# 如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,
# 或其中的一方的长度为1。
arr1 = np.array([[0], [1], [2], [3]])
arr1.shape # (4, 1) 四行一列

arr2 = np.array([1, 2, 3])
arr2.shape # (3,)一行三列

arr1 + arr2
# arr1 + arr2的结果如下:
# array([[1, 2, 3],
# [2, 3, 4],
# [3, 4, 5],
# [4, 5, 6]])

附录:Ndarray的类型

名称 描述 简写
np.bool 用一个字节存储的布尔类型(True或False) ‘b’
np.int8 一个字节大小,-128 至 127 ‘i’
np.int16 整数,-32768 至 32767 ‘i2’
np.int32 整数,-2^31 至 2^32 -1 ‘i4’
np.int64 整数,-2^63 至 2^63 - 1 ‘i8’
np.uint8 无符号整数,0 至 255 ‘u’
np.uint16 无符号整数,0 至 65535 ‘u2’
np.uint32 无符号整数,0 至 2^32 - 1 ‘u4’
np.uint64 无符号整数,0 至 2^64 - 1 ‘u8’
np.float16 半精度浮点数:16位,正负号1位,指数5位,精度10位 ‘f2’
np.float32 单精度浮点数:32位,正负号1位,指数8位,精度23位 ‘f4’
np.float64 双精度浮点数:64位,正负号1位,指数11位,精度52位 ‘f8’
np.complex64 复数,分别用两个32位浮点数表示实部和虚部 ‘c8’
np.complex128 复数,分别用两个64位浮点数表示实部和虚部 ‘c16’
np.object_ python对象 ‘O’
np.string_ 字符串 ‘S’
np.unicode_ unicode类型 ‘U’