Python学习笔记:numpy基础使用

本文最后更新于:2024年3月29日 上午

1 数据维度

1.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
import numpy as np

# 创建一个一维array对象
arr1 = np.array([2, 4, 6, 8])
print("arr1数据:\n", arr1, "\narr1维度:", arr1.ndim)

# 创建一个二维array对象
arr2 = np.array([[2, 4, 6, 8],
[6, 8, 10, 12],
[8, 10, 12, 14]])
print("arr2数据:\n", arr2, "\narr2维度:", arr2.ndim)

# 创建一个三维array对象
arr3 = np.array([
[
[2, 4, 6, 8],
[6, 8, 10, 12],
[8, 10, 12, 14]
],
[
[21, 41, 6, 8],
[61, 81, 10, 12],
[81, 101, 12, 14]
],

])
print("arr3数据:\n", arr3, "\narr3维度:", arr3.ndim)

运行结果如下:

array.ndim可以得到Numpy Array对象的维度。

1.2 添加数据

1.2.1 一维数据

一维数据直接使用np.concatenate

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

arr1 = np.array([2, 4, 6, 8])
arr2 = np.array([10, 12])
arr = np.concatenate([arr1, arr2])
print("arr1数据:", arr1, "\narr1维度:", arr1.ndim)
print("arr2数据:", arr2, "\narr2维度:", arr2.ndim)
print("arr数据:", arr, "\narr维度:", arr.ndim)

输出结果:

1.2.2 二维数据

首先需要添加一个维度,然后在第一个维度上添加数据。

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

arr1 = np.array([2, 4, 6, 8])
arr2 = np.array([10, 12, 14, 16])
# 首先把它们都变成二维,以下两种方法都可以
arr1 = np.expand_dims(arr1, 0)
arr2 = arr2[np.newaxis, :]

print("arr1加维度后:", arr1)
print("arr2加维度后:", arr2)

# 然后再在第一个维度上叠加
arr = np.concatenate([arr1, arr2])
print("扩展后:\n", arr)

输出结果:

1.3 合并数据

上述是在第一个维度上叠加,也可以在第二个维度上叠加,只需要给np.concatenate输入一个参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
arr1 = np.array([2, 4, 6, 8])
arr2 = np.array([10, 12, 14, 16])
# 首先把它们都变成二维,以下两种方法都可以
arr1 = np.expand_dims(arr1, 0)
arr2 = arr2[np.newaxis, :]

print("arr1加维度后:", arr1)
print("arr2加维度后:", arr2)

arr = np.concatenate([arr1, arr2], axis=0)
print("第一维度叠加:\n", arr)

arr = np.concatenate([arr1, arr2], axis=1)
print("第二维度叠加:\n", arr)

输出结果:

只要维度可以对齐,可以在任意维度上进行合并操作,但是有些数据维度对不齐,就无法合并,例如:

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

arr1 = np.array([[2, 4, 6, 8], [1, 2, 3, 4]])
arr2 = np.array([[10, 12, 14], [3, 2, 1]])

# arr = np.concatenate([arr1, arr2], axis=0) # error
# print("第一维度叠加:\n", arr)

arr = np.concatenate([arr1, arr2], axis=1)
print("第二维度叠加:\n", arr)

对于二维数据,可以使用np.vstack()np.hstack()进行竖直和水平合并:

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

arr1 = np.array([[2, 4, 6, 8], [1, 2, 3, 4]])
arr2 = np.array([[10, 12, 14, 16], [3, 2, 1, 0]])

arr = np.vstack([arr1, arr2])
print("竖直合并:\n", arr)

arr = np.hstack([arr1, arr2])
print("水平合并:\n", arr)

输出结果:

1.4 观察形态

可以使用array.size获取元素总个数,使用np.shape获取行数和列数:

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

arr = np.array([[2, 4, 6, 8], [1, 2, 3, 4]])

# 元素总数
print("元素总数:", arr.size)

# 行数和列数
print("第一个维度(行):", arr.shape[0])
print("第二个维度(列):", arr.shape[1])
print("所有维度:", arr.shape)

# 三维数据
arr1 = np.array([
[
[1, 2, 1], [2, 3, 1], [1, 2, 1], [1, 2, 1]
],
[
[3, 4, 1], [1, 2, 1], [1, 2, 1], [4, 5, 1]
]
])

# 元素总数
print("元素总数:", arr1.size)

# 行数和列数
print("第一个维度:", arr1.shape[0])
print("第二个维度:", arr1.shape[1])
print("第三个维度:", arr1.shape[2])
print("所有维度:", arr1.shape)

输出结果:

2 数据选择

2.1 单个选取

可以直接用索引取值,也可以一次取多个:

1
2
3
4
5
6
import numpy as np

a = np.array([1, 2, 3])
print("a[0]:", a[0])
print("a[1]:", a[1])
print("a[0,1]:", a[[0, 1]])

输出结果:

二维数据:

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

b = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])

# 选第 2 行所有数
print("b[1]:\n", b[1])

# 选第 2 行,第 1 列的数
print("b[1,0]:\n", b[1, 0])

# 这里有点别扭,第一个数组表示行数,第二个数组表示列数,如果对应到数据,
# 第一个拿的是数据位是 [1,2]
# 第二个拿的是 [0,3]
print("b[[1,0],[2,3]]:\n",
b[[1, 0],
[2, 3]])

输出结果:

2.2 切片划分

一般形式为array[a:b,c:d]a:b表示从第一个维度从a到b-1,以此类推,:前缺省值为最小,:后缺省值为最大,例如:

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

b = np.array([
[
[1, 2, 3, 4],
[5, 6, 7, 8],
],
[
[9, 10, 11, 12],
[13, 14, 15, 16]
],
[
[17, 18, 19, 20],
[21, 22, 23, 24]
]
])

print("***********b[:2]************:\n", b[:2])
print("*********b[:2, 1:2]*********:\n", b[:2, 1:2])
print("*****b[1:3, 1:2, -3:-2]*****:\n", b[1:3, 1:2, -3:-2])

输出结果为:

2.3 条件筛选

上述选择方式是按照位置进行选择,下面介绍按照条件进行选择数据的方式。

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

a = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])

print(a[a > 7])

输出结果:

上面选取的a中大于7的数据,下面演示了a[a>7]中发生了什么。

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

a = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])

condition = a > 7
print("condition:\n", condition)

print("a[condition]:\n", a[condition])

从图中可以看出,condition是一种True/False,则只要我们得到一个True/False数据,我们就可以筛选,这就是它筛选的底层逻辑。

除了这种直接使用[]的形式,Numpy还有一个专用的函数来做数据筛选,还可以将满足条件的位置变成设定的数字。

下面展示了将上述a中大于7的数据变成1,否则就是0:

3 基础运算

3.1 加减乘除

Numpy Array对象可以直接使用+-*/进行运算,如:

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

a = np.array([1, 2, 3, 4])

print("a + 3:", a + 3)
print("a - 3:", a - 3)
print("a * 3:", a * 3)
print("a / 3:", a / 3)

输出结果:

矩阵的点积运算:

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

a = np.array([
[1, 2],
[3, 4]
])
b = np.array([
[5, 6],
[7, 8]
])

print(a.dot(b))
print(np.dot(a, b))

两种方法结果一样:

还有矩阵外积np.outer()、矩阵内积np.inner()(和np.dot()略有不同,可以理解为np.dot(a,b) = np.inner(a,b.transpose()))。

3.2 数据统计分析

可以通过以下方法获得最值、累加、累乘、平均数等统计参数,注意有些方法具有两种写法,比如np.max(a)a.max();有的只有一种写法,比如np.median(a)

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

a = np.array([0, 1, 32, 56, 20, 0, 13, 1])

print("最大:", np.max(a), a.max())
print("最小:", np.min(a), a.min())
print("累加:", np.sum(a), a.sum())
print("累乘:", np.prod(a), a.prod())
print("总数:", np.size(a), a.size)
print("平均数:", np.mean(a), a.mean())
print("标准差:", np.std(a), a.std())
# 以下只有一种方法
print("中位数:", np.median(a))
print("非零总数:", np.count_nonzero(a))

3.3 特殊运算符号

3.3.1 定位最值

有时候我们不关心最大值和最小值是多少,我们关心的是其对应的序号,此时可以使用np.argmax()np.argmin(),比如:

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

a = np.array([150, 166, 183, 170])
name = ["小明", "小红", "小刚", "小亮"]
high_idx = np.argmax(a)
low_idx = np.argmin(a)
print("{} 最高".format(name[high_idx]))
print("{} 最矮".format(name[low_idx]))

输出结果:

3.3.2 取整

1
2
3
4
5
import numpy as np

a = np.array([150.1, 166.4, 183.7, 170.8])
print("向上取整:", np.ceil(a))
print("向下取整:", np.floor(a))

输出结果:

3.3.3 取值截取

给定一组数据和上下限,需要将小于下限的值赋值下限,大于上限的值赋值上限,如下:

1
2
3
4
import numpy as np

a = np.array([150.1, 166.4, 183.7, 170.8])
print("clip:", a.clip(160, 180))

输出结果:

4 改变数据姿态

4.1 添加维度

可以使用np.newaxis,其实它和None一样,比如:

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

a = np.array([1, 2, 3, 4, 5, 6])

a_2d = a[np.newaxis, :]
print("np.newaxis: ", np.newaxis)
print("a_2d: ", a_2d, a_2d.shape)

a_none = a[:, None]
print("a_none: ", a_none, a_none.shape)

输出结果:

可以看出np.newaxis其值就是None,需要注意添加维度的位置。

利用np.expand_dims()函数:

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

a = np.array([1, 2, 3, 4, 5, 6])

a_expand = np.expand_dims(a, axis=0)
print("a_expand.shape: ", a_expand, a_expand.shape)
a_expand = np.expand_dims(a, axis=1)
print("a_expand.shape: ", a_expand, a_expand.shape)

输出结果:

除了添加维度,还可以减少维度,当然只能减少shape为1的那些维度,因为这样减掉该维度后不丢失数据:

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

a = np.array([1, 2, 3, 4, 5, 6])

a_expand = np.expand_dims(a, axis=1)
print("a_expand.shape: ", a_expand, a_expand.shape)

a_squeeze = np.squeeze(a_expand)
a_squeeze_axis = a_expand.squeeze(axis=1)
print(a_squeeze, a_squeeze.shape)
print(a_squeeze_axis, a_squeeze_axis.shape)

输出结果:

可以使用np.reshape()改变数据结构,让数据重新“站队”:

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

a = np.array([1, 2, 3, 4, 5, 6])
a1 = a.reshape([2, 3])
a2 = a.reshape([3, 1, 2])
print("a1 shape:", a1.shape)
print(a1)
print("a2 shape:", a2.shape)
print(a2)

输出结果:

4.2 合并

np.column_stack()np.row_stack()合并:

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

feature_a = np.array([1, 2, 3, 4, 5, 6])
feature_b = np.array([11, 22, 33, 44, 55, 66])
c_stack = np.column_stack([feature_a, feature_b])
print(c_stack)

sample_a = np.array([0, 1.1, 12, 1, 2.3, 1])
sample_b = np.array([1, 2.2, 12, 12, 123, 1])
c_stack = np.row_stack([sample_a, sample_b])
print(c_stack)

看似与np.vstacknp.hstack()类似,但是它们存在一些区别,比如:

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

feature_a = np.array([1, 2, 3, 4, 5, 6])[:, None]
feature_b = np.array([11, 22, 33, 44, 55, 66])[:, None]
c_stack = np.hstack([feature_a, feature_b])
print(c_stack)

sample_a = np.array([0, 1.1])[None, :]
sample_b = np.array([1, 2.2])[None, :]
c_stack = np.vstack([sample_a, sample_b])
print(c_stack)

使用np.vstacknp.hstack()必须先保证维度信息是正确的,而np.column_stack()np.row_stack()会自动处理维度信息。

使用np.concatenate()可以在任意维度合并:

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

a = np.array([
[1, 2],
[3, 4]
])
b = np.array([
[5, 6],
[7, 8]
])

print(np.concatenate([a, b], axis=0))
print(np.concatenate([a, b], axis=1))

4.3 拆解

np.vsplit()np.hsplit()实现横着、竖着拆解。

如果直接在 indices_or_sections 后填入数字,就是要整分的段数, 而如果接着的是一个列表,那就按照列表中的 index 来取区间。

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

a = np.array(
[[1, 11, 2, 22],
[3, 33, 4, 44],
[5, 55, 6, 66],
[7, 77, 8, 88]]
)
print(np.vsplit(a, indices_or_sections=2)) # 分成两段
print(np.vsplit(a, indices_or_sections=[2, 3])) # 分片成 [:2],[2:3], [3:]

输出结果:

np.split()在任一维度拆解:

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

a = np.array(
[[1, 11, 2, 22],
[3, 33, 4, 44],
[5, 55, 6, 66],
[7, 77, 8, 88]]
)
print(np.split(a, indices_or_sections=2, axis=0)) # 分成两段
print(np.split(a, indices_or_sections=[2, 3], axis=1)) # 在第二维度,分片成 [:2],[2:3],[3:]

输出结果:

5 设置输出格式

1
np.set_printoptions(precision=None, threshold=None,  linewidth=None, suppress=None, formatter=None)
  • precision:控制输出结果的精度(即小数点后的位数),默认值为8

  • threshold:当数组元素总数过大时,设置显示的数字位数,其余用省略号代替(当数组元素总数大于设置值,控制输出值得个数为6个,当数组元素小于或者等于设置值得时候,全部显示),当设置值为sys.maxsize(需要导入sys库),则会输出所有元素

  • linewidth:每行字符的数目,其余的数值会换到下一行

  • suppress:小数是否需要以科学计数法的形式输出

  • formatter:自定义输出规则

6 矩阵相关

6.1 矩阵求逆

np.linalg.inv(A)

如果是矩阵对象(np.matrix),可以直接通过.I求逆。

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

a = np.array([[1, 2], [3, 4]]) # 初始化一个非奇异矩阵(数组)
print(np.linalg.inv(a)) # 对应于MATLAB中 inv() 函数

# 矩阵对象可以通过 .I 更方便的求逆
A = np.matrix(a)
print(A.I)

6.2 矩阵求特征值及特征向量

np.linalg.eig(A)

1
2
3
4
5
6
mat = np.array([[0, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 1, 1, 0]])
eigen_value, feature_vector = np.linalg.eig(mat)

参考资料:Numpy 数据怪兽 | 莫烦Python (mofanpy.com).


Python学习笔记:numpy基础使用
https://summersong.top/post/70407431.html
作者
SummerSong
发布于
2022年8月27日
更新于
2024年3月29日
许可协议