Python 数值分析

第一章: NumPy 数组

1、初识数组

1.1 数组的类型

实操1:创建整数型数组(默认类型)

in1

python 复制代码
import numpy as np # 使用numpy需先导入,重命名为np(行业通用写法)
# 整数型数组(输入均为整数,默认类型np.int64)
int_arr = np.array([1, 2, 3])
print(int_arr)  # 打印数组内容
print(int_arr.dtype)  # 打印数组数据类型

实操2:创建浮点型数组(默认类型)

in2

python 复制代码
# 浮点型数组(输入含小数,默认类型np.float64)
float_arr = np.array([1.0, 2.5, 3.1])
print(float_arr)
print(float_arr.dtype)

实操3:创建布尔型数组(数组和常数比较)

in3

python 复制代码
int_arr = np.array([1, 2, 3])
bool_arr = int_arr >= 2
print(bool_arr)
print(bool_arr.dtype)

实操4:创建布尔型数组(数组和数组比较)

in4

python 复制代码
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([6, 2, 1, 5, 3])
bool_arr = arr1 >= arr2 
print(bool_arr)
print(bool_arr.dtype)

实操5: np.where(布尔数组) 的使用

in5

python 复制代码
int_arr = np.array([1, 2, 3])
bool_arr = int_arr >= 2
print(np.where(bool_arr ))

1.2 同化定理

实操1:向上同化(整数与浮点数混合)

in1

python 复制代码
import numpy as np
# 输入含整数和浮点数,触发向上同化(整数 → 浮点数)
mixed_arr = np.array([1, 2, 3.14])
print(mixed_arr)
print(mixed_arr.dtype)

实操2:被集体同化(向整型数组插入浮点数)

in2

python 复制代码
# 创建整型数组(类型为int64)
int_arr = np.array([1, 2, 3])
# 插入浮点数3.14,被集体同化为整型(截断小数部分)
int_arr[2] = 3.14
print(int_arr)
print(int_arr.dtype)

实操3:被集体同化(向浮点型数组插入整数)

in3

python 复制代码
# 创建浮点型数组(类型为float64)
float_arr = np.array([1.0, 2.0, 3.0])
# 插入整数4,被集体同化为浮点型
float_arr[2] = 4
print(float_arr)
print(float_arr.dtype)

1.3 共同改变定理

实操1:浮点型数组转为整型数组

in1

python 复制代码
import numpy as np
# 创建浮点型数组
float_arr = np.array([1.0, 2.0, 3.0])
# 转为整型数组(astype(int))
int_arr = float_arr.astype(int)
print(int_arr)
print(int_arr.dtype)

实操2:整型数组转为浮点型数组

in2

python 复制代码
# 创建整型数组
int_arr = np.array([1, 2, 3])
# 转为浮点型数组(astype(float))
float_arr = int_arr.astype(float)
print(float_arr)
print(float_arr.dtype)

2. 数组的创建

实操1:创建一维指定数组

in1

python 复制代码
import numpy as np
arr1 = np.array([1, 2, 3])
print(arr1)

实操2:创建二维指定数组

in2

python 复制代码
arr2 = np.array([[1, 2], [3, 4]])
print(arr2)

2.2 创建递增数组

实操1:用np.arange()创建递增数组(按步长)

in1

python 复制代码
import numpy as np
arr_range = np.arange(0, 10, 2)
print(arr_range)

实操2:用np.linspace()创建递增数组(按元素个数)

in2

python 复制代码
arr_lin = np.linspace(0, 1, 5)
print(arr_lin)

out2

python 复制代码
[0.   0.25 0.5  0.75 1.  ]

2.3 创建同值数组

实操1:用 np.zeros() 创建全0数组

in1

python 复制代码
import numpy as np
zeros_arr = np.zeros((2, 3))
print(zeros_arr)

实操2:用np.full()创建指定值数组

in2

python 复制代码
full_arr = np.full((2, 2), 7)
print(full_arr)

2.4 创建未初始化数组

实操1:创建未初始化数组

in1

python 复制代码
import numpy as np

empty_arr = np.empty((2, 3))
print(empty_arr)

实操2:创建指定数据类型的未初始化数组

in2

python 复制代码
empty_int_arr = np.empty((2, 2), dtype=int)
print(empty_int_arr)

2.5 创建随机数组

实操1:生成均匀分布随机数组

in1

python 复制代码
import numpy as np
# 生成 2x2 的均匀分布随机数组
rand_arr = np.random.rand(2, 2)
print(rand_arr)

实操2:生成随机整数数组

in2

python 复制代码
# 生成 0到9 之间的随机整数数组
randint_arr = np.random.randint(0, 10, size=(2, 3))
print(randint_arr)

实操3:用np.random.seed()固定随机种子

in3

python 复制代码
# 固定随机种子(数值可自定义,如100)
np.random.seed(100)
# 生成2x2均匀分布随机数组
rand_arr1 = np.random.rand(2, 2)
print("固定种子后第一次生成的随机数组:")
print(rand_arr1)

# 再次生成相同维度的随机数组(种子不变,结果一致)
rand_arr2 = np.random.rand(2, 2)
print("\n固定种子后第二次生成的随机数组:")
print(rand_arr2)

# 更换随机种子,生成的数组会变化
np.random.seed(200)
rand_arr3 = np.random.rand(2, 2)
print("\n更换种子后生成的随机数组:")
print(rand_arr3)

3. 数组的索引

3.1 基础元素访问

实操1:一维数组访问单个元素

in1

python 复制代码
import numpy as np
# 创建一维数组
arr = np.array([10, 20, 30, 40, 50])
# 访问第0个元素(索引从0开始)
print("第0个元素:", arr[0])
# 访问最后一个元素(负索引)
print("最后一个元素:", arr[-1])

out1

python 复制代码
第0个元素: 10
最后一个元素: 50

实操2:多维数组访问单个元素

in2

python 复制代码
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr[0, 1])  # 访问第0行,第1列的元素

out2

python 复制代码
2

3.2 花式索引

实操1:一维数组花式索引

in1

python 复制代码
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
indices = [0, 2, 4]
print(arr[indices])

out1

python 复制代码
[10 30 50]

实操2:二维数组花式索引(批量访问指定行)

in2

python 复制代码
# 创建二维数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 批量访问第0行和第2行
row_indices = [0, 2]
print(arr[row_indices])

out2

python 复制代码
[[1 2 3]
 [7 8 9]]

实操3:二维数组花式索引(批量访问指定行列)

in3

python 复制代码
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 批量访问第0、2行,第1、2列
row_indices = [0, 2]
col_indices = [1, 2]
print(arr[row_indices, col_indices])

out3

python 复制代码
[2 9]

实操4:二维数组花式索引(行列组合精准访问)

in4

python 复制代码
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 访问(0行1列)、(1行2列)、(2行0列)的元素
print(arr[[0, 1, 2], [1, 2, 0]])

out4

python 复制代码
[2 6 7]

3.3 数组切片

实操1:一维数组切片

in1

python 复制代码
import numpy as np
arr = np.array([0, 1, 2, 3, 4, 5])
print(arr[1:4])  # 从索引1开始,到索引4结束(不包含4),步长默认1

out1

python 复制代码
[1 2 3]

实操2:二维数组切片

in2

python 复制代码
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix[:2, 1:])  # 获取前两行,第1列及以后的元素

out2

python 复制代码
[[2 3]
 [5 6]]

实操3:指定步长切片

in3

python 复制代码
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 从索引0开始,到索引9结束,步长为2(每隔1个元素提取)
print(arr[0:9:2])

out3

python 复制代码
[0 2 4 6 8]

3.4 数组切片仅是视图

实操1:修改切片视图影响原数组

in1

复制代码

import numpy as np arr = np.array([1, 2, 3, 4]) slice_arr = arr[1:3] slice_arr[0] = 99 print(arr) # 原数组也会被修改

out1

复制代码

[ 1 99 3 4]

实操2:使用copy()获取切片副本(不影响原数组)

in2

复制代码

arr = np.array([1, 2, 3, 4]) # 显式调用copy()获取副本 slice_arr = arr[1:3].copy() slice_arr[0] = 99 print("切片副本:", slice_arr) print("原数组:", arr) # 原数组不受影响

out2

复制代码

切片副本: [99 3] 原数组: [1 2 3 4]

3.5 数组赋值仅是绑定

实操1:直接赋值(绑定引用)

in1

复制代码

import numpy as np a = np.array([1, 2, 3]) b = a b[0] = 100 print(a)

out1

复制代码

[100 2 3]

实操2:使用copy()创建副本(避免绑定)

in2

复制代码

a = np.array([1, 2, 3]) # 使用copy()创建副本,避免绑定 b = a.copy() b[0] = 100 print("变量a:", a) print("变量b(副本):", b)

out2

复制代码

变量a: [1 2 3] 变量b(副本): [100 2 3]

4. 数组的变形

4.1 数组的转置

实操1:二维数组转置(使用.T属性)

in1

复制代码

import numpy as np arr = np.array([[1, 2], [3, 4]]) print("原二维数组:") print(arr) print("\n转置后的数组:") print(arr.T)

out1

复制代码

原二维数组: [[1 2] [3 4]] 转置后的数组: [[1 3] [2 4]]

实操2:二维数组转置(使用transpose()方法)

in2

复制代码

arr = np.array([[1, 2, 3], [4, 5, 6]]) print("原二维数组:") print(arr) print("\ntranspose()转置后:") print(arr.transpose())

out2

复制代码

原二维数组: [[1 2 3] [4 5 6]] transpose()转置后: [[1 4] [2 5] [3 6]]

4.2 数组的翻转

实操1:一维数组整体翻转(切片法)

in1

复制代码

import numpy as np arr = np.array([1, 2, 3, 4]) print("原一维数组:", arr) print("翻转后数组:", arr[::-1])

out1

复制代码

原一维数组: [1 2 3 4] 翻转后数组: [4 3 2 1]

实操2:二维数组垂直翻转(np.flip(),axis=0)

in2

复制代码

matrix = np.array([[1, 2], [3, 4], [5, 6]]) print("原二维数组:") print(matrix) print("\n垂直翻转(axis=0):") print(np.flip(matrix, axis=0))

out2

复制代码

原二维数组: [[1 2] [3 4] [5 6]] 垂直翻转(axis=0): [[5 6] [3 4] [1 2]]

实操3:二维数组水平翻转(np.flip(),axis=1)

in3

复制代码

matrix = np.array([[1, 2], [3, 4], [5, 6]]) print("原二维数组:") print(matrix) print("\n水平翻转(axis=1):") print(np.flip(matrix, axis=1))

out3

复制代码

原二维数组: [[1 2] [3 4] [5 6]] 水平翻转(axis=1): [[2 1] [4 3] [6 5]]

4.3 数组的重塑

实操1:一维数组重塑为二维数组

in1

复制代码

import numpy as np arr = np.arange(6) # 生成0-5的一维数组,共6个元素 print("原一维数组:", arr) # 重塑为2行3列的二维数组(元素总数2*3=6,与原数组一致) reshaped = arr.reshape(2, 3) print("\n重塑为2行3列:") print(reshaped)

out1

复制代码

原一维数组: [0 1 2 3 4 5] 重塑为2行3列: [[0 1 2] [3 4 5]]

实操2:使用-1作为维度占位符重塑

in2

复制代码

arr = np.arange(12) # 生成0-11的一维数组,共12个元素 print("原一维数组:", arr) # 指定行数为3,列数用-1自动计算(12/3=4) reshaped1 = arr.reshape(3, -1) print("\n重塑为3行(列数自动计算):") print(reshaped1) # 指定列数为6,行数用-1自动计算(12/6=2) reshaped2 = arr.reshape(-1, 6) print("\n重塑为6列(行数自动计算):") print(reshaped2)

out2

复制代码

原一维数组: [ 0 1 2 3 4 5 6 7 8 9 10 11] 重塑为3行(列数自动计算): [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] 重塑为6列(行数自动计算): [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]]

4.4 数组的拼接

实操1:垂直拼接(np.vstack())

in1

复制代码

import numpy as np a = np.array([[1, 2]]) # 1行2列 b = np.array([[3, 4]]) # 1行2列(列数与a一致,可垂直拼接) print("数组a:") print(a) print("数组b:") print(b) print("\n垂直拼接(vstack):") print(np.vstack((a, b)))

out1

复制代码

数组a: [[1 2]] 数组b: [[3 4]] 垂直拼接(vstack): [[1 2] [3 4]]

实操2:水平拼接(np.hstack())

in2

复制代码

a = np.array([[1], [2]]) # 2行1列 b = np.array([[3], [4]]) # 2行1列(行数与a一致,可水平拼接) print("数组a:") print(a) print("数组b:") print(b) print("\n水平拼接(hstack):") print(np.hstack((a, b)))

out2

复制代码

数组a: [[1] [2]] 数组b: [[3] [4]] 水平拼接(hstack): [[1 3] [2 4]]

实操3:多数组拼接(np.concatenate())

in3

复制代码

a = np.array([[1, 2], [3, 4]]) b = np.array([[5, 6], [7, 8]]) c = np.array([[9, 10], [11, 12]]) print("数组a:") print(a) print("数组b:") print(b) print("数组c:") print(c) # 垂直拼接3个数组(axis=0) print("垂直拼接3个数组:") print(np.concatenate((a, b, c), axis=0)) # 水平拼接3个数组(axis=1) print("\n水平拼接3个数组:") print(np.concatenate((a, b, c), axis=1))

out3

复制代码

数组a: [[1 2] [3 4]] 数组b: [[5 6] [7 8]] 数组c: [[ 9 10] [11 12]] 垂直拼接3个数组: [[ 1 2] [ 3 4] [ 5 6] [ 7 8] [ 9 10] [11 12]] 水平拼接3个数组: [[ 1 2 5 6 9 10] [ 3 4 7 8 11 12]]

np.vstack()np.hstack()np.concatenate()的简化版,语法更简洁,优先推荐用于简单拼接场景。

4.5 数组的分裂

实操1:按份数分裂一维数组

in1

复制代码

import numpy as np arr = np.arange(9) # 0-8,共9个元素,可被3整除 print("原一维数组:", arr) # 平均分成3份(indices_or_sections=3) split_arr = np.split(arr, 3) print("\n分裂为3个子数组:") for i, sub_arr in enumerate(split_arr): print(f"子数组{i+1}:", sub_arr)

out1

复制代码

原一维数组: [0 1 2 3 4 5 6 7 8] 分裂为3个子数组: 子数组1: [0 1 2] 子数组2: [3 4 5] 子数组3: [6 7 8]

实操2:按指定位置分裂二维数组(垂直分裂)

in2

复制代码

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) print("原二维数组:") print(arr) # 按行位置1、3分裂(axis=0,即垂直分裂) split_arr = np.split(arr, [1, 3], axis=0) print("\n按指定位置垂直分裂:") for i, sub_arr in enumerate(split_arr): print(f"子数组{i+1}:") print(sub_arr)

out2

复制代码

原二维数组: [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]] 按指定位置垂直分裂: 子数组1: [[1 2 3]] 子数组2: [[4 5 6] [7 8 9]] 子数组3: [[10 11 12]]

实操3 :垂直分列二维数组(np.vspilt())

int3:

复制代码

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) print("原二维数组:") print(arr) # 按行位置1、3分裂(axis=0,即垂直分裂) split_arr = np.vsplit(arr, [1, 3]) print("\n按指定位置垂直分裂:") for i, sub_arr in enumerate(split_arr): print(f"子数组{i+1}:") print(sub_arr)

out3:

复制代码

原二维数组: [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]] 按指定位置垂直分裂: 子数组1: [[1 2 3]] 子数组2: [[4 5 6] [7 8 9]] 子数组3: [[10 11 12]]

实操4:水平分裂二维数组(np.hsplit())

in4

复制代码

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) print("原二维数组:") print(arr) # 水平分裂为2份(列数4可被2整除) split_arr = np.hsplit(arr, 2) print("\n水平分裂为2个子数组:") for i, sub_arr in enumerate(split_arr): print(f"子数组{i+1}:") print(sub_arr)

out4

复制代码

原二维数组: [[1 2 3 4] [5 6 7 8]] 水平分裂为2个子数组: 子数组1: [[1 2] [5 6]] 子数组2: [[3 4] [7 8]]

5、数组的运算

5.1 数组与标量之间的运算

实操1:基础标量运算(加、减、乘、除)

In 1:

复制代码

import numpy as np # 必导库,固定写法 arr = np.array([1, 2, 3]) # 创建一维数组(可替换为自身数据) # 分别执行加、减、乘、除运算 print("数组+2:", arr + 2) print("数组-1:", arr - 1) print("数组*2:", arr * 2) print("数组/2:", arr / 2)

Out1:

复制代码

数组+2: [3 4 5] 数组-1: [0 1 2] 数组*2: [2 4 6] 数组/2: [0.5 1. 1.5]

实操2:标量幂运算

In 2:

复制代码

# 沿用上面的arr数组,计算数组每个元素的平方、立方 print("数组元素平方:", arr ** 2) print("数组元素立方:", arr ** 3)

Out2:

复制代码

数组元素平方: [1 4 9] 数组元素立方: [ 1 8 27]

5.2 数组与数组之间的运算

实操1:同形状数组基础运算

In 1:

复制代码

import numpy as np # 创建两个形状相同的一维数组(可替换为自身数据,确保形状一致) a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) # 分别执行加、减、乘、除运算 print("a + b:", a + b) print("a - b:", a - b) print("a * b:", a * b) print("a / b:", a / b)

Out1:

复制代码

a + b: [5 7 9] a - b: [-3 -3 -3] a * b: [ 4 10 18] a / b: [0.25 0.4 0.5 ]

实操2:同形状二维数组运算

In 2:

复制代码

# 创建两个2行3列的二维数组(形状一致) a = np.array([[1, 2, 3], [4, 5, 6]]) b = np.array([[7, 8, 9], [10, 11, 12]]) print("二维数组a * b:") print(a * b)

Out2:

复制代码

二维数组a * b: [[ 7 16 27] [40 55 72]]

5.3 广播

实操1:二维数组与一维数组广播(最常用场景)

In 1:

复制代码

import numpy as np # 二维数组(形状 (2, 3)),一维数组(形状 (3,)),最后一个维度相等,可广播 matrix = np.array([[1, 2, 3], [4, 5, 6]]) vec = np.array([10, 20, 30]) # vec自动扩展为 [[10,20,30], [10,20,30]](形状 (2,3),再与matrix相加 result = matrix + vec print("广播运算结果:") print(result)

Out1:

复制代码

广播运算结果: [[11 22 33] [14 25 36]]

实操2:不同维度数组广播(补1扩展)

In 2:

复制代码

# 一维数组(形状 (3,)),标量(可看作形状 (1,)),可广播 arr = np.array([1, 2, 3]) scalar = 5 # scalar自动扩展为 [5,5,5],再与arr相乘 print("标量与数组广播:", arr * scalar)

Out2:

复制代码

标量与数组广播: [ 5 10 15]

In 3:

三维数组与二维数组广播(补1+扩展):

复制代码

import numpy as np # 三维数组(形状 (2,1,3))与二维数组(形状 (3,3)),补1后维度匹配,可广播 arr3d = np.array([[[1,2,3]], [[4,5,6]]]) arr2d = np.array([[10,20,30], [40,50,60], [70,80,90]]) print("\n三维数组形状:") print(arr3d.shape) print("\n二维数组形状:") print(arr2d.shape) print("\n三维与二维数组广播运算后的形状:") result = arr3d + arr2d print(result.shape)

Out3:

复制代码

三维数组形状: (2, 1, 3) 二维数组形状: (3, 3) 三维与二维数组广播运算后的形状: (2, 3, 3)

6. 数组的函数

6.1 矩阵乘积

三、NumPy代码实现

In 1:

复制代码

import numpy as np # 必导库,确保代码可独立运行 # 创建两个可相乘的二维矩阵(第一个列数=第二个行数=2) A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) # 两种矩阵乘法写法,结果一致 print("np.dot()实现矩阵乘积:") print(np.dot(A, B)) print("\n@运算符实现矩阵乘积:") print(A @ B)

Out1:

复制代码

np.dot()实现矩阵乘积: [[19 22] [43 50]] @运算符实现矩阵乘积: [[19 22] [43 50]]

实操2:形状不匹配导致ValueError(无法运算场景)

In 2:

复制代码

# 创建形状不匹配的两个矩阵(A列数=2,B行数=3,不满足矩阵乘法前提) A = np.array([[1, 2], [3, 4]]) # 形状(2,2),列数=2 B = np.array([[5, 6], [7, 8], [9, 10]]) # 形状(3,2),行数=3 # 尝试矩阵乘法,会抛出ValueError try: print(A @ B) except ValueError as e: print("报错信息:", e)

Out2:

复制代码

报错信息: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 3 is different from 2)

实操3:演示矩阵乘法不满足交换律(A@B ≠ B@A)

In 3:

复制代码

# 创建两个可相乘的矩阵(形状均为(2,2),满足乘法前提) A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) # 计算A@B和B@A,对比结果 result1 = A @ B # A乘B result2 = B @ A # B乘A print("A @ B 的结果:") print(result1) print("\nB @ A 的结果:") print(result2) print("\nA@B 与 B@A 是否相等?", np.array_equal(result1, result2))

Out3:

复制代码

A @ B 的结果: [[19 22] [43 50]] B @ A 的结果: [[23 34] [31 46]] A@B 与 B@A 是否相等? False

6.2 数学函数

实操1:常用数学函数实操

In 1:

复制代码

import numpy as np # 创建测试数组(覆盖正数、平方数,适配多数数学函数) arr = np.array([1, 4, 9, -4, 0]) # 逐一演示常用数学函数 print("数组平方根:", np.sqrt(np.abs(arr))) # 先取绝对值,避免负数报错 print("数组自然指数:", np.exp(arr[:3])) # 取前3个正数计算指数 print("数组绝对值:", np.abs(arr)) print("数组正弦值(弧度):", np.sin(np.array([0, np.pi/2, np.pi])))

Out1:

复制代码

数组平方根: [1. 2. 3. 2. 0.] 数组自然指数: [2.71828183e+00 5.45981500e+01 8.10308393e+03] 数组绝对值: [1 4 9 4 0] 数组正弦值(弧度): [0.0000000e+00 1.0000000e+00 1.2246468e-16]

6.3 统计与聚合函数

实操1:聚合函数实操(所有元素求和)

In 1:

复制代码

import numpy as np # 创建二维测试矩阵 matrix = np.array([[1, 2, 3], [4, 5, 6]]) # 所有元素求和(默认axis=None) print("矩阵所有元素求和:", np.sum(matrix))

Out1:

复制代码

21

实操2:聚合函数实操(按列/行求和)

In 2:

复制代码

# 沿用上述matrix矩阵 print("按列求和(axis=0):", np.sum(matrix, axis=0)) # 每列元素相加 print("按行求和(axis=1):", np.sum(matrix, axis=1)) # 每行元素相加 print("按列求平均值:", np.mean(matrix, axis=0)) print("矩阵最大值:", np.max(matrix))

Out2:

复制代码

按列求和(axis=0): [5 7 9] 按行求和(axis=1): [ 6 15] 按列求平均值: [2.5 3.5 4.5] 矩阵最大值: 6

实操3:中位数与平均值对比(观察极端值影响)

In 3:

复制代码

import numpy as np # 创建包含极端值的数组arr = np.array([1, 2, 3, 100])# 对比平均值与中位数 print("数组平均值:", np.mean(arr)) print("数组中位数:", np.median(arr))

Out3:

复制代码

数组平均值: 26.5 数组中位数: 2.5

实操4:标准差与方差实操(衡量数据波动)

In 4:

复制代码

import numpy as np # 创建测试数组arr = np.array([1, 2, 3, 4, 5])# 计算方差与标准差 print("数组方差:", np.var(arr)) print("数组标准差:", np.std(arr))

Out4:

复制代码

数组方差: 2.0 数组标准差: 1.4142135623730951

实操5:百分位数实操(统计数据分布)

In 5:

复制代码

import numpy as np # 创建测试数组arr = np.array([10, 20, 30, 40, 50])# 计算不同百分位数 print("25%百分位数:", np.percentile(arr, 25)) print("50%百分位数:", np.percentile(arr, 50)) print("75%百分位数:", np.percentile(arr, 75))

Out5:

复制代码

25%百分位数: 20.0 50%百分位数: 30.0 75%百分位数: 40.0

实操6:累积和与累积积实操

In 6:

复制代码

import numpy as np # 创建测试数组arr = np.array([1, 2, 3, 4])# 累积和print("数组累积和:", np.cumsum(arr))# 累积积 print("数组累积积:", np.cumprod(arr))

Out6:

复制代码

数组累积和: [ 1 3 6 10] 数组累积积: [ 1 2 6 24]

6.4 比较函数

实操1:数组元素比较运算(逐元素比较)

In 1:

复制代码

import numpy as np # 创建测试数组 arr = np.array([1, 3, 5, 7]) # 逐元素比较 print("数组元素是否大于3:", arr > 3) print("数组元素是否等于5:", arr == 5) print("数组元素是否小于等于3:", arr <= 3)

Out1:

复制代码

数组元素是否大于3: [False False True True] 数组元素是否等于5: [False False True False] 数组元素是否小于等于3: [ True True False False]

实操2:条件筛选(提取满足条件的数据)

In 2:

复制代码

import numpy as np # 创建测试数组 arr = np.array([1, 3, 5, 7, 9]) # 筛选大于5的元素 print("筛选大于5的元素:", arr[arr > 5]) # 筛选偶数元素 print("筛选偶数元素:", arr[arr % 2 == 0])

Out2:

复制代码

筛选大于5的元素: [7 9] 筛选偶数元素: []

实操3:argmax与argmin实操(查找最大值/最小值位置)

In 3:

复制代码

import numpy as np # 创建测试数组 arr = np.array([10, 50, 30, 80, 20]) # 查找最大值与最小值索引 print("最大值索引:", np.argmax(arr)) print("最小值索引:", np.argmin(arr))

Out3:

复制代码

最大值索引: 3 最小值索引: 0

实操4:any与all实操(整体条件判断)

In 4:

复制代码

import numpy as np # 创建布尔数组 arr = np.array([True, True, False]) # 判断条件 print("是否至少存在一个True:", np.any(arr)) print("是否全部为True:", np.all(arr))

Out4:

复制代码

是否至少存在一个True: True 是否全部为True: False

实操5:np.where()条件判断实操

In 5:

复制代码

import numpy as np # 创建测试数组 arr = np.array([60, 75, 45, 90]) # 成绩分类 result = np.where(arr >= 60, "及格", "不及格") print("成绩分类结果:") print(result)

Out5:

复制代码

成绩分类结果: ['及格' '及格' '不及格' '及格']

6.5 排序函数

实操1:一维数组排序(基础排序,可直接复用)

In 1:

复制代码

import numpy as np # 创建测试数组 arr = np.array([5, 2, 8, 1, 3]) # 对数组进行升序排序 sorted_arr = np.sort(arr) print("原数组:", arr) print("排序后数组:", sorted_arr)

Out1:

复制代码

原数组: [5 2 8 1 3] 排序后数组: [1 2 3 5 8

实操2:原数组直接排序(sort方法实操)

In 2:

复制代码

import numpy as np # 创建测试数组 arr = np.array([5, 2, 8, 1, 3]) # 直接修改原数组排序 arr.sort() print("排序后的原数组:", arr)

Out2:

复制代码

排序后的原数组: [1 2 3 5 8]

实操3:二维数组按行/按列排序(axis参数核心实操)

In 3:

复制代码

import numpy as np # 创建二维数组 matrix = np.array([[3, 1, 2], [6, 5, 4]]) # 按列排序 print("按列排序(axis=0):") print(np.sort(matrix, axis=0)) # 按行排序 print("\n按行排序(axis=1):") print(np.sort(matrix, axis=1))

Out3:

复制代码

按列排序(axis=0): [[3 1 2] [6 5 4]] 按行排序(axis=1): [[1 2 3] [4 5 6]]

实操4:降序排序(反转切片实操)

In 4:

复制代码

import numpy as np # 创建测试数组 arr = np.array([5, 2, 8, 1, 3]) # 先升序排序,再反转实现降序 desc_arr = np.sort(arr)[::-1] print("降序排序结果:", desc_arr)

Out4:

复制代码

降序排序结果: [8 5 3 2 1]

实操5:argsort获取排序索引(重点实操)

In 5:

复制代码

import numpy as np # 创建测试数组 arr = np.array([50, 10, 30]) # 获取排序后的索引位置 index_arr = np.argsort(arr) print("排序索引:", index_arr) print("根据索引排序后的结果:", arr[index_arr])

Out5:

复制代码

排序索引: [1 2 0] 根据索引排序后的结果: [10 30 50]

实操6:最大值与最大值索引(排行榜场景)

In 6:

复制代码

import numpy as np # 创建测试数组 score = np.array([88, 95, 76, 99, 90]) # 获取最大值及索引 print("最高分:", np.max(score)) print("最高分索引:", np.argmax(score))

Out6:

复制代码

最高分: 99 最高分索引: 3

第二章:Pandas 数据分析基础

2. 创建 Pandas 对象

2.1 Series对象的创建

方式1:从列表创建Series(最常用)

in1

复制代码

# 导入pandas库,一般我们用pd来表示 import pandas as pd val1 = [10, 20, 30, 40, 50] s1 = pd.Series(val1 ) print("方式1-列表创建的Series:") print(s1) print("Series的数据类型:", type(s1))

out1

复制代码

方式1-列表创建的Series: 0 10 1 20 2 30 3 40 4 50 dtype: int64 Series的数据类型: <class 'pandas.core.series.Series'>

方式2:指定索引创建Series(自定义标签)

in2

复制代码

val2 = ["苹果", "香蕉", "橙子", "葡萄"] index2 = ["水果1", "水果2", "水果3", "水果4"] s2 = pd.Series(val2 , index=index2) print("\n方式2-指定索引的Series:") print(s2)

out2

复制代码

方式2-指定索引的Series: 水果1 苹果 水果2 香蕉 水果3 橙子 水果4 葡萄 dtype: object

方式3:从字典创建Series(字典的key自动作为索引)

in3

复制代码

dict1 = {"姓名": "张三", "年龄": 20, "性别": "男", "成绩": 95} s3 = pd.Series(dict1) print("\n方式3-字典创建的Series:") print(s3)

out3

复制代码

方式3-字典创建的Series: 姓名 张三 年龄 20 性别 男 成绩 95 dtype: object

证明:可重复索引的Series

in4

复制代码

# 1. 尝试创建key重复的字典(会报错,证明字典key不可重复) dict_dup = {"水果": "苹果", "水果": "香蕉", "蔬菜": "黄瓜"} print("重复key的字典:", dict_dup) # 2. 创建索引(key)重复的Series(正常运行,证明Series允许重复索引) data_dup = ["苹果", "香蕉", "黄瓜"] index_dup = ["水果", "水果", "蔬菜"] # 重复索引"水果" s_dup = pd.Series(data_dup, index=index_dup) print("\n重复索引的Series:") print(s_dup) print("重复索引的取值:", s_dup["水果"]) # 可获取所有重复索引对应的数据

out4

复制代码

重复key的字典: {'水果': '香蕉', '蔬菜': '黄瓜'} 重复索引的Series: 水果 苹果 水果 香蕉 蔬菜 黄瓜 dtype: object 重复索引的取值: 水果 苹果 水果 香蕉 dtype: object

方式5:从NumPy数组创建Series(依托NumPy基础)

in5

复制代码

#导入numpy库 import numpy as np data4 = np.array([15, 25, 35, 45, 55]) # 先创建NumPy数组 s4 = pd.Series(data4) # 转换为Series,默认索引从0开始 print("方式5-NumPy数组创建的Series:") print(s4) print("Series的数据类型:", type(s4)) print("Series底层的NumPy数组:", s4.values)

out5

复制代码

方式5-NumPy数组创建的Series: 0 15 1 25 2 35 3 45 4 55 dtype: int64 Series的数据类型: <class 'pandas.Series'> Series底层的NumPy数组: [15 25 35 45 55]

2.2 Series的属性

1. index属性:获取Series的索引标签

in1

复制代码

# 先导入所需库,创建示例Series(本小节独立实操,重新定义) import pandas as pd # 定义示例Series,沿用前文逻辑,保证实操连贯性 data2 = ["苹果", "香蕉", "橙子", "葡萄"] index2 = ["水果1", "水果2", "水果3", "水果4"] s2 = pd.Series(data2, index=index2) data3 = {"姓名": "张三", "年龄": 20, "性别": "男", "成绩": 95} s3 = pd.Series(data3) # 查看索引 print("s2的索引(index):") print(s2.index) print("索引的数据类型:", type(s2.index)) print("\ns3的索引(index):") print(s3.index)

out1

复制代码

s2的索引(index): Index(['水果1', '水果2', '水果3', '水果4'], dtype='object') 索引的数据类型: <class 'pandas.core.indexes.base.Index'> s3的索引(index): Index(['姓名', '年龄', '性别', '成绩'], dtype='object')

2. values属性:获取Series的数据值

in2

复制代码

# 导入numpy库,对values进行操作 import numpy as np # 查看s2和s3的数据值,以及数据值的类型 print("s2的数据值(values):") print(s2.values) print("数据值的数据类型:", type(s2.values)) print("\ns3的数据值(values):") print(s3.values) # 对values进行NumPy操作(示例:求最大值,仅适用于数值型数据) print("\ns3中数值型数据的最大值:", np.max(s3.values[1::2])) # 取年龄和成绩求最大值

out2

复制代码

s2的数据值(values): ['苹果' '香蕉' '橙子' '葡萄'] 数据值的数据类型: <class 'numpy.ndarray'> s3的数据值(values): ['张三' 20 '男' 95] s3中数值型数据的最大值: 95

2.3 DataFrame对象的创建

方式1:从列表嵌套列表创建(指定列索引)

in1

复制代码

import pandas as pd # 方式1:从列表嵌套列 表创建(指定列索引) data1 = [ ["张三", 20, "男", 98], ["李四", 19, "女", 92], ["王五", 21, "男", 88], ["赵六", 18, "女", 95] ] columns1 = ["姓名", "年龄", "性别", "成绩"] # 列索引(表头) df1 = pd.DataFrame(data1, columns=columns1) print("方式1-列表嵌套创建的DataFrame:") print(df1)

out1

复制代码

方式1-列表嵌套创建的DataFrame: 姓名 年龄 性别 成绩 0 张三 20 男 98 1 李四 19 女 92 2 王五 21 男 88 3 赵六 18 女 95

方式2:从字典创建(字典的key作为列索引columns)

in2

复制代码

# 方式2:从字典创建(字典的key作为列索引) data2 = { "姓名": ["张三", "李四", "王五", "赵六"], "年龄": [20, 19, 21, 18], "性别": ["男", "女", "男", "女"], "成绩": [98, 92, 88, 95] } df2 = pd.DataFrame(data2) print("\n方式2-字典创建的DataFrame:") print(df2)

out2

复制代码

方式2-字典创建的DataFrame: 姓名 年龄 性别 成绩 0 张三 20 男 98 1 李四 19 女 92 2 王五 21 男 88 3 赵六 18 女 95

方式3:从Series创建(多个Series组成DataFrame)

in3

复制代码

# 方式3:从Series创建(多个Series组成DataFrame) s_name = pd.Series(["张三", "李四", "王五", "赵六"], name="姓名") s_age = pd.Series([20, 19, 21, 18], name="年龄") s_gender = pd.Series(["男", "女", "男", "女"], name="性别") df3 = pd.DataFrame([s_name, s_age, s_gender]).T # .T表示转置(行变列) print("\n方式3-Series创建的DataFrame:") print(df3)

out3

复制代码

方式3-Series创建的DataFrame: 姓名 年龄 性别 0 张三 20 男 1 李四 19 女 2 王五 21 男 3 赵六 18 女

方式4:从NumPy数组创建(指定行、列索引)

in4

复制代码

data4 = np.random.randint(60, 100, size=(4, 3)) # 4行3列的随机整数(60-100) index4 = ["学生1", "学生2", "学生3", "学生4"] # 行索引 columns4 = ["语文", "数学", "英语"] # 列索引 df4 = pd.DataFrame(data4, index=index4, columns=columns4) print("\n方式4-NumPy数组创建的DataFrame:") print(df4)

out4

复制代码

语文 数学 英语 学生1 85 72 93 学生2 68 91 77 学生3 95 88 69 学生4 76 83 90 (注:因np.random.randint为随机生成,实际输出数值会有所不同)

2.4 DataFrame对象的属性

1. index属性:获取DataFrame的行索引

in1

复制代码

# 先导入所需库 import pandas as pd import numpy as np data1 = [ ["张三", 20, "男", 98], ["李四", 19, "女", 92], ["王五", 21, "男", 88], ["赵六", 18, "女", 95] ] columns1 = ["姓名", "年龄", "性别", "成绩"] df1 = pd.DataFrame(data1, columns=columns1) data4 = np.random.randint(60, 100, size=(4, 3)) index4 = ["学生1", "学生2", "学生3", "学生4"] columns4 = ["语文", "数学", "英语"] df4 = pd.DataFrame(data4, index=index4, columns=columns4) # 访问并查看行索引 print("df1的行索引(index):") print(df1.index) print("df1行索引的类型:", type(df1.index)) print("\ndf4的行索引(index):") print(df4.index) print("df4行索引的类型:", type(df4.index))

out1

复制代码

df1的行索引(index): RangeIndex(start=0, stop=4, step=1) df1行索引的类型: <class 'pandas.core.indexes.range.RangeIndex'> df4的行索引(index): Index(['学生1', '学生2', '学生3', '学生4'], dtype='object') df4行索引的类型: <class 'pandas.core.indexes.base.Index'>

2. columns 属性:获取DataFrame的列索引

in2

复制代码

# 访问并查看列索引 print("df1的列索引(columns):") print(df1.columns) print("df1列索引的类型:", type(df1.columns)) print("\ndf4的列索引(columns):") print(df4.columns) print("df4列索引的类型:", type(df4.columns))

out2

复制代码

df1的列索引(columns): Index(['姓名', '年龄', '性别', '成绩'], dtype='object') df1列索引的类型: <class 'pandas.core.indexes.base.Index'> df4的列索引(columns): Index(['语文', '数学', '英语'], dtype='object') df4列索引的类型: <class 'pandas.core.indexes.base.Index'>

3. values属性:获取DataFrame的原始数据

in3

复制代码

# 访问并查看原始数据,及对数据进行简单操作 print("df1的原始数据(values):") print(df1.values) print("df1数据的类型:", type(df1.values)) print("\ndf4的原始数据(values):") print(df4.values) print("df4数据的类型:", type(df4.values)) # 基于values数组进行简单数值计算(仅适用于数值型数据) print("\ndf4各科平均分:", np.mean(df4.values, axis=0)) # axis=0表示按列计算

out3

复制代码

df1的原始数据(values): [['张三' 20 '男' 98] ['李四' 19 '女' 92] ['王五' 21 '男' 88] ['赵六' 18 '女' 95]] df1数据的类型: <class 'numpy.ndarray'> df4的原始数据(values): [[72 66 90] [82 81 66] [77 81 72] [87 67 69]] df4数据的类型: <class 'numpy.ndarray'> df4各科平均分: [79.5 73.75 74.25]

3. 索引详解

3.1 隐式索引和显式索引

实操1:Series 的隐式索引与显式索引对比(创建对比)

in1

复制代码

# 导入所需库 import pandas as pd import numpy as np # 隐式索引(未指定index,自动生成0,1,2,3) s_implicit = pd.Series([10, 20, 30, 40]) # 显式索引(手动指定index为字符串标签) s_explicit = pd.Series([10, 20, 30, 40], index=["a", "b", "c", "d"]) # 打印对比结果 print("=== Series 索引对比 ====") print("隐式索引Series:") print(s_implicit) print("\n显式索引Series:") print(s_explicit)

out1

复制代码

=== Series 索引对比 ==== 隐式索引Series: 0 10 1 20 2 30 3 40 dtype: int64 显式索引Series: a 10 b 20 c 30 d 40 dtype: int64

实操2:Series 的隐式索引与显式索引对比(切片对比)

in2

复制代码

# 补充:切片访问对比(核心区别:隐式左闭右开,显式左闭右闭) print("=== Series 切片访问对比 ====") # 隐式索引切片(按位置,左闭右开,不包含结束位置3) print("隐式索引切片(0:3):", s_implicit[0:3]) # 显式索引切片(按标签,左闭右闭,包含结束标签'c') print("显式索引切片(a:c):", s_explicit["a":"c"])

out2

复制代码

=== Series 切片访问对比 ==== 隐式索引切片(0:3): 0 10 1 20 2 30 dtype: int64 显式索引切片(a:c): a 10 b 20 c 30 dtype: int64

实操3:DataFrame 的隐式索引与显式索引对比(创建对比)

in3

复制代码

# 导入所需库 import pandas as pd import numpy as np # 隐式索引(未指定index,自动生成0,1,2) df_implicit = pd.DataFrame( data=[[88, 92], [78, 85], [95, 89]], columns=["语文", "数学"] ) # 显式索引(手动指定行索引index和列索引columns) df_explicit = pd.DataFrame( data=[[88, 92], [78, 85], [95, 89]], index=["张三", "李四", "王五"], columns=["语文", "数学"] ) # 打印对比结果 print("=== DataFrame 索引对比 ====") print("隐式行索引DataFrame:") print(df_implicit) print("\n显式行索引DataFrame:") print(df_explicit)

out3

复制代码

=== DataFrame 索引对比 === 隐式行索引DataFrame: 语文 数学 0 88 92 1 78 85 2 95 89 显式行索引DataFrame: 语文 数学 张三 88 92 李四 78 85 王五 95 89

实操4:DataFrame 的隐式索引与显式索引对比(切片对比)

in4

复制代码

# 补充:DataFrame行索引切片访问对比 print("=== DataFrame 行索引切片访问对比 ====") # 隐式行索引切片(按位置,左闭右开,不包含结束位置2) print("隐式行索引切片(0:2):") print(df_implicit.iloc[0:2]) # 显式行索引切片(按标签,左闭右闭,包含结束标签'李四') print("\n显式行索引切片(张三:李四):") print(df_explicit.loc["张三":"李四"])

out4

复制代码

=== DataFrame 行索引切片访问对比 ==== 隐式行索引切片(0:2): 语文 数学 0 88 92 1 78 85 显式行索引切片(张三:李四): 语文 数学 张三 88 92 李四 78 85

3.2 Series 的索引

3.2.1 Series 隐式索引操作

实操1:隐式索引取值(按位置)- 直接按位置取值

in1

复制代码

# 导入所需库,创建隐式索引Series import pandas as pd s_implicit = pd.Series([10, 20, 30, 40, 50, 60]) print("隐式索引Series原始数据:") print(s_implicit) # 1. 直接按位置取值(隐式索引) print("\n1. 直接按位置取值:") print("第0个位置的数据:", s_implicit[0]) print("第1-2个位置的数据(切片):", s_implicit[1:3]) # 切片左闭右开

out1

复制代码

隐式索引Series原始数据: 0 10 1 20 2 30 3 40 4 50 5 60 dtype: int64 1. 直接按位置取值: 第0个位置的数据: 10 第1-2个位置的数据(切片): 1 20 2 30 dtype: int64

实操2:隐式索引取值(按位置)- iloc按位置取值(强制指定使用隐式索引)

in2

复制代码

# 2. 通过iloc按位置取值(推荐,明确区分隐式索引) print("2. iloc按位置取值:") print("第3个位置的数据:", s_implicit.iloc[3]) print("第0、2个位置的数据(列表索引):", s_implicit.iloc[[0, 2]])

out2

复制代码

2. iloc按位置取值: 第3个位置的数据: 40 第0、2个位置的数据(列表索引): 0 10 2 30 dtype: int64

实操3:隐式索引取值(按位置)- 隐式索引切片访问详解

in3

复制代码

# 3. 隐式索引切片访问详解(iloc,左闭右开) print("3. 隐式索引切片访问(iloc,左闭右开):") print("切片1-4(不包含4):", s_implicit.iloc[1:4]) # 取位置1、2、3 print("间隔切片(步长2):", s_implicit.iloc[0:6:2]) # 取位置0、2、4 print("反向切片(从后往前):", s_implicit.iloc[-3:-1]) # 取倒数第3、2个位置

out3

复制代码

3. 隐式索引切片访问(iloc,左闭右开): 切片1-4(不包含4): 1 20 2 30 3 40 dtype: int64 间隔切片(步长2): 0 10 2 30 4 50 dtype: int64 反向切片(从后往前): 3 40 4 50 dtype: int64

3.2.2 Series显式索引操作

实操1:显式索引取值(按标签)-

in1

复制代码

# 导入所需库,创建显式索引Series import pandas as pd s_explicit = pd.Series([10, 20, 30, 40, 50, 60], index=["a", "b", "c", "d", "e", "f"]) print("显式索引Series原始数据:") print(s_explicit) # 1. 直接按标签取值(显式索引) print("\n1. 直接按标签取值:") print("标签'a'对应的数据:", s_explicit["a"]) print("标签'c'对应的数据:", s_explicit["c"]) print("标签'b'和'e'对应的数据(列表索引):", s_explicit[["b", "e"]])

out1

复制代码

显式索引Series原始数据: a 10 b 20 c 30 d 40 e 50 f 60 dtype: int64 1. 直接按标签取值: 标签'a'对应的数据: 10 标签'c'对应的数据: 30 标签'b'和'e'对应的数据(列表索引): b 20 e 50 dtype: int64

实操2:显式索引取值(按标签)- loc按标签取值

in2

复制代码

# 2. 通过loc按标签取值(推荐,明确区分显式索引) print("2. loc按标签取值:") print("标签'd'对应的数据:", s_explicit.loc["d"]) print("标签'a'、'c'、'f'对应的数据(列表索引):", s_explicit.loc[["a", "c", "f"]])

out2

复制代码

2. loc按标签取值: 标签'd'对应的数据: 40 标签'a'、'c'、'f'对应的数据(列表索引): a 10 c 30 f 60 dtype: int64

实操2:显式索引取值(按标签)- 显式索引切片访问详解

in3

复制代码

# 3. 显式索引切片访问详解(loc,左闭右闭) print("3. 显式索引切片访问(loc,左闭右闭):") print("切片b:e(包含e):", s_explicit.loc["b":"e"]) # 取标签b、c、d、e print("间隔切片(步长2):", s_explicit.loc["a":"f":2]) # 取标签a、c、e print("反向切片(从后往前):", s_explicit.loc["f":"c":-1]) # 取标签f、e、d、c

out3

复制代码

3. 显式索引切片访问(loc,左闭右闭): 切片b:e(包含e): b 20 c 30 d 40 e 50 dtype: int64 间隔切片(步长2): a 10 c 30 e 50 dtype: int64 反向切片(从后往前): f 60 e 50 d 40 c 30 dtype: int64

3.3 DataFrame 的索引

3.3.1 DataFrame 行索引操作

实操1:隐式行索引 - 单行取值

in1

复制代码

# 导入所需库,创建示例DataFrame(显式行索引,显式列索引) import pandas as pd import numpy as np data = [ ["张三", 20, "男", 98], ["李四", 19, "女", 92], ["王五", 21, "男", 88], ["赵六", 18, "女", 95], ["孙七", 20, "男", 90] ] df = pd.DataFrame( data, columns=["姓名", "年龄", "性别", "成绩"] # 显式列索引 ) print("示例DataFrame:") print(df) print("\n隐式行索引 - 取第0行数据(iloc):") print(df.iloc[0]) # 单行,返回Series

out1

复制代码

姓名 年龄 性别 成绩 0 张三 20 男 98 1 李四 19 女 92 2 王五 21 男 88 3 赵六 18 女 95 4 孙七 20 男 90 姓名 张三 年龄 20 性别 男 成绩 98 Name: 0, dtype: object 姓名 年龄 性别 成绩 1 李四 19 女 92 2 王五 21 男 88 3 赵六 18 女 95

实操2:隐式行索引 - 多行切片取值

in2

复制代码

print("隐式行索引 - 取第1-3行数据(切片,左闭右开):") print(df.iloc[1:4]) # 多行,返回DataFrame,包含位置1、2、3,不包含4

out2

复制代码

隐式行索引 - 取第1-3行数据(切片,左闭右开): 姓名 年龄 性别 成绩 1 李四 19 女 92 2 王五 21 男 88 3 赵六 18 女 95

实操3:隐式行索引 - 列表索引取值

in3

复制代码

print("隐式行索引 - 取第0、2、4行数据(列表索引):") print(df.iloc[[0, 2, 4]]) # 指定多个位置,返回DataFrame

out3

复制代码

隐式行索引 - 取第0、2、4行数据(列表索引): 姓名 年龄 性别 成绩 0 张三 20 男 98 2 王五 21 男 88 4 孙七 20 男 90

3.3.1.2 显式行索引操作(按标签,loc)

实操1:显式行索引 - 单行取值

in1

复制代码

# 导入所需库,创建示例DataFrame import pandas as pd import numpy as np data = [ ["张三", 20, "男", 98], ["李四", 19, "女", 92], ["王五", 21, "男", 88], ["赵六", 18, "女", 95], ["孙七", 20, "男", 90] ] df = pd.DataFrame( data, index=["学员1", "学员2", "学员3", "学员4", "学员5"], columns=["姓名", "年龄", "性别", "成绩"] ) # 沿用DataFrame(df) print("示例DataFrame:") print(df) print("\n显式行索引 - 取标签'学员3'对应行数据(loc):") print(df.loc["学员3"]) # 单行,返回Series

out1

复制代码

示例DataFrame: 姓名 年龄 性别 成绩 学员1 张三 20 男 98 学员2 李四 19 女 92 学员3 王五 21 男 88 学员4 赵六 18 女 95 学员5 孙七 20 男 90 显式行索引 - 取标签'学员3'对应行数据(loc): 姓名 王五 年龄 21 性别 男 成绩 88 Name: 学员3, dtype: object

实操2:显式行索引 - 多行切片取值

in2

复制代码

print("显式行索引 - 取标签'学员2'到'学员4'对应行数据(切片,左闭右闭):") print(df.loc["学员2":"学员4"]) # 多行,返回DataFrame,包含两端标签

out2

复制代码

显式行索引 - 取标签'学员2'到'学员4'对应行数据(切片,左闭右闭): 姓名 年龄 性别 成绩 学员2 李四 19 女 92 学员3 王五 21 男 88 学员4 赵六 18 女 95

实操3:显式行索引 - 列表索引取值

in3

复制代码

print("显式行索引 - 取标签'学员1'、'学员5'对应行数据(列表索引):") print(df.loc[["学员1", "学员5"]]) # 指定多个标签,返回DataFrame

out3

复制代码

显式行索引 - 取标签'学员1'、'学员5'对应行数据(列表索引): 姓名 年龄 性别 成绩 学员1 张三 20 男 98 学员5 孙七 20 男 90

3.3.2 DataFrame 列索引操作
3.3.2.1 隐式列索引操作(按位置,iloc)

实操1:隐式列索引 - 单列取值

in1

复制代码

# 沿用上面的示例DataFrame(df) print("示例DataFrame:") print(df) print("\n隐式列索引 - 取第0列数据(姓名列,iloc):") print(df.iloc[:, 0]) # 冒号表示所有行,0表示第0列,返回Series

out1

复制代码

学员1 张三 学员2 李四 学员3 王五 学员4 赵六 学员5 孙七

实操2:隐式列索引 - 多列切片取值

in2

复制代码

# 沿用上面的示例DataFrame(df) print("隐式列索引 - 取第2-3列数据(性别、成绩列,切片左闭右开):") print(df.iloc[:, 2:4]) # 所有行,第2、3列,返回DataFrame

out2

复制代码

2 3 学员1 男 98 学员2 女 92 学员3 男 88 学员4 女 95 学员5 男 90

实操3:隐式列索引 - 列表索引取值

in3

复制代码

# 沿用上面的示例DataFrame(df) print("隐式列索引 - 取第1、3列数据(年龄、成绩列,列表索引):") print(df.iloc[:, [1, 3]]) # 所有行,第1、3列,返回DataFrame

out3

复制代码

1 3 学员1 20 98 学员2 19 92 学员3 21 88 学员4 18 95 学员5 20 90

3.3.2.2 显式列索引操作(按标签,loc/直接取值)

实操1:显式列索引 - 直接按标签取值(单列)

in1

复制代码

# 导入所需库,创建示例DataFrame(显式行索引,显式列索引) import pandas as pd import numpy as np data = [ ["张三", 20, "男", 98], ["李四", 19, "女", 92], ["王五", 21, "男", 88], ["赵六", 18, "女", 95], ["孙七", 20, "男", 90] ] df = pd.DataFrame( data, index=["学员1", "学员2", "学员3", "学员4", "学员5"], # 显式行索引(用于对比) columns=["姓名", "年龄", "性别", "成绩"] # 显式列索引 ) print("示例DataFrame:") print(df) print("\n显式列索引 - 直接取'姓名'列数据:") print(df["姓名"]) # 单列,返回Series

out1

复制代码

示例DataFrame: 姓名 年龄 性别 成绩 学员1 张三 20 男 98 学员2 李四 19 女 92 学员3 王五 21 男 88 学员4 赵六 18 女 95 学员5 孙七 20 男 90 显式列索引 - 直接取'姓名'列数据: 学员1 张三 学员2 李四 学员3 王五 学员4 赵六 学员5 孙七 Name: 姓名, dtype: object

实操2:显式列索引 - 直接按标签取值(多列)

in2

复制代码

# 沿用上面的示例DataFrame(df) print("显式列索引 - 直接取'年龄'和'成绩'列数据:") print(df.loc[["年龄", "成绩"]]) # 多列,返回DataFrame

out2

复制代码

显式列索引 - 直接取'年龄'和'成绩'列数据: 年龄 成绩 学员1 20 98 学员2 19 92 学员3 21 88 学员4 18 95 学员5 20 90

实操3:显式列索引 - 使用loc按标签取值(单列)

in3

复制代码

# 沿用上面的示例DataFrame(df) print("显式列索引 - 使用loc取'性别'列数据:") print(df.loc[:, "性别"]) # 冒号表示所有行,"性别"表示列标签,返回Series

out3

复制代码

显式列索引 - 使用loc取'性别'列数据: 学员1 男 学员2 女 学员3 男 学员4 女 学员5 男 Name: 性别, dtype: str

实操4:显式列索引 - 使用loc按标签取值(多列切片)

in4

复制代码

# 沿用上面的示例DataFrame(df) print("显式列索引 - 使用loc取'姓名'到'成绩'列数据(切片,左闭右闭):") print(df.loc[:, "姓名":"成绩"]) # 所有行,包含"姓名"到"成绩"的所有列

out4

复制代码

显式列索引 - 使用loc取'姓名'到'成绩'列数据(切片,左闭右闭): 姓名 年龄 性别 成绩 学员1 张三 20 男 98 学员2 李四 19 女 92 学员3 王五 21 男 88 学员4 赵六 18 女 95 学员5 孙七 20 男 90

3.3.3 DataFrame 行列联合索引操作
3.3.3.1 按位置联合索引(iloc)

实操1:按位置联合索引 - 单行单列(具体单元格)

in1

复制代码

# 导入所需库,创建示例DataFrame(显式行索引,显式列索引) import pandas as pd import numpy as np data = [ ["张三", 20, "男", 98], ["李四", 19, "女", 92], ["王五", 21, "男", 88], ["赵六", 18, "女", 95], ["孙七", 20, "男", 90] ] df = pd.DataFrame( data, index=["学员1", "学员2", "学员3", "学员4", "学员5"], # 显式行索引(用于对比) columns=["姓名", "年龄", "性别", "成绩"] # 显式列索引 ) # 沿用上面的示例DataFrame(df) print("示例DataFrame:") print(df) print("\n按位置联合索引 - 取第0行第3列数据(学员1的成绩):") print(df.iloc[0, 3]) # 行位置0,列位置3,返回单个数据值

out1

复制代码

示例DataFrame: 姓名 年龄 性别 成绩 学员1 张三 20 男 98 学员2 李四 19 女 92 学员3 王五 21 男 88 学员4 赵六 18 女 95 学员5 孙七 20 男 90 按位置联合索引 - 取第0行第3列数据(学员1的成绩): 98

实操2:按位置联合索引 - 多行多列(切片)

in2

复制代码

# 沿用上面的示例DataFrame(df) print("按位置联合索引 - 取第1-3行第1-2列数据(学员2-4的年龄、性别):") print(df.iloc[1:4, 1:3]) # 行切片1-4(左闭右开),列切片1-3(左闭右开)

out2

复制代码

按位置联合索引 - 取第1-3行第1-2列数据(学员2-4的年龄、性别): 年龄 性别 学员2 19 女 学员3 21 男 学员4 18 女

实操3:按位置联合索引 - 多行多列(列表索引)

in3

复制代码

# 沿用上面的示例DataFrame(df) print("按位置联合索引 - 取第0、2行第0、3列数据(学员1、3的姓名、成绩):") print(df.iloc[[0, 2], [0, 3]]) # 行列表[0,2],列列表[0,3]

out3

复制代码

按位置联合索引 - 取第0、2行第0、3列数据(学员1、3的姓名、成绩): 姓名 成绩 学员1 张三 98 学员3 王五 88

3.3.3.2 按标签联合索引(loc)

实操1:按标签联合索引 - 单行单列(具体单元格)

in1

复制代码

# 沿用上面的示例DataFrame(df) print("示例DataFrame:") print(df) print("\n按标签联合索引 - 取学员3的成绩:") print(df.loc["学员3", "成绩"]) # 行标签"学员3",列标签"成绩",返回单个数据值

out1

复制代码

示例DataFrame: 姓名 年龄 性别 成绩 学员1 张三 20 男 98 学员2 李四 19 女 92 学员3 王五 21 男 88 学员4 赵六 18 女 95 学员5 孙七 20 男 90 按标签联合索引 - 取学员3的成绩: 88

实操2:按标签联合索引 - 多行多列(列表+切片)

in2

复制代码

# 沿用上面的示例DataFrame(df) print("按标签联合索引 - 取学员2-4的姓名、成绩:") print(df.loc["学员2":"学员4", ["姓名", "成绩"]]) # 行切片,列列表

out2

复制代码

按标签联合索引 - 取学员2-4的姓名、成绩: 姓名 成绩 学员2 李四 92 学员3 王五 88 学员4 赵六 95

实操3:按标签联合索引 - 多行多列(列表+切片)

in3

复制代码

# 沿用上面的示例DataFrame(df) print("按标签联合索引 - 取学员1、5的年龄、性别:") print(df.loc[["学员1", "学员5"], "年龄":"性别"]) # 行列表,列切片

out3

复制代码

按标签联合索引 - 取学员1、5的年龄、性别: 年龄 性别 学员1 20 男 学员5 20 男

3.4 索引的修改与重置

实操1:索引的修改(行索引/列索引)

in1

复制代码

# 导入所需库,创建示例DataFrame import pandas as pd data = [["张三", 98], ["李四", 92], ["王五", 88]] df = pd.DataFrame(data, columns=["姓名", "成绩"]) print("修改前的DataFrame:") print(df) print("修改前行索引:", df.index) print("修改前列索引:", df.columns) # 1. 修改行索引(index) df.index = ["No.1", "No.2", "No.3"] # 新行索引,长度与原索引一致(3个) # 2. 修改列索引(columns) df.columns = ["student_name", "student_score"] # 新列索引,长度与原索引一致(2个) print("\n修改后的DataFrame:") print(df) print("修改后行索引:", df.index) print("修改后列索引:", df.columns)

out1

复制代码

修改前的DataFrame: 姓名 成绩 0 张三 98 1 李四 92 2 王五 88 修改前行索引: RangeIndex(start=0, stop=3, step=1) 修改前列索引: Index(['姓名', '成绩'], dtype='str') 修改后的DataFrame: student_name student_score No.1 张三 98 No.2 李四 92 No.3 王五 88 修改后行索引: Index(['No.1', 'No.2', 'No.3'], dtype='str') 修改后列索引: Index(['student_name', 'student_score'], dtype='str')

实操2:索引的重置(reset_index)

in2

复制代码

# 沿用上面修改后的DataFrame(df) print("重置前的DataFrame:") print(df) # 1. 重置索引(保留原索引,作为新列) df_reset1 = df.reset_index() print("\n1. 保留原索引的重置结果:") print(df_reset1) # 2. 重置索引(不保留原索引,直接删除) df_reset2 = df.reset_index(drop=True) print("\n2. 不保留原索引的重置结果:") print(df_reset2)

out2

复制代码

重置前的DataFrame: student_name student_score No.1 张三 98 No.2 李四 92 No.3 王五 88 1. 保留原索引的重置结果: index student_name student_score 0 No.1 张三 98 1 No.2 李四 92 2 No.3 王五 88 2. 不保留原索引的重置结果: student_name student_score 0 张三 98 1 李四 92 2 王五 88

4. Pandas 常用方法

4.1 Series 常用方法

4.1.1 数值统计方法

in1

复制代码

import pandas as pd s = pd.Series([10, 20, 30, 40, 50]) print("求和:", s.sum()) print("平均值:", s.mean()) print("最大值:", s.max()) print("最小值:", s.min()) print("标准差:", s.std()) print("方差:", s.var()) print("中位数:", s.median()) print("非空元素个数:", s.count())

out1

复制代码

求和: 150 平均值: 30.0 最大值: 50 最小值: 10 标准差: 15.811388300841896 方差: 250.0 中位数: 30.0 非空元素个数: 5

4.1.2 排序方法

in2

复制代码

s = pd.Series( [88, 95, 76], index=["张三", "李四", "王五"] ) print("按数据值升序排序:") print(s.sort_values()) print("\n按数据值降序排序:") print(s.sort_values(ascending=False)) print("\n按索引排序:") print(s.sort_index())

out2

复制代码

按数据值升序排序: 王五 76 张三 88 李四 95 dtype: int64 按数据值降序排序: 李四 95 张三 88 王五 76 dtype: int64 按索引排序: 张三 88 李四 95 王五 76 dtype: int64

4.1.3 去重与唯一值方法

in3

复制代码

s = pd.Series([1, 2, 2, 3, 3, 3]) print("唯一值:", s.unique()) print("唯一值个数:", s.nunique()) print("\n删除重复值:") print(s.drop_duplicates())

out3

复制代码

唯一值: [1 2 3] 唯一值个数: 3 删除重复值: 0 1 1 2 3 3 dtype: int64

4.1.4 value_counts()统计方法

in4

复制代码

s = pd.Series(["苹果", "香蕉", "苹果", "橙子", "苹果"]) print("统计每个元素出现次数:") print(s.value_counts())

out4

复制代码

统计每个元素出现次数: 苹果 3 香蕉 1 橙子 1 dtype: int64

4.1.5 缺失值处理方法

in5

复制代码

import numpy as np s = pd.Series([10, np.nan, 30, np.nan, 50]) print("判断是否为空:") print(s.isna()) print("\n删除缺失值:") print(s.dropna()) print("\n使用0填充缺失值:") print(s.fillna(0))

out5

复制代码

判断是否为空: 0 False 1 True 2 False 3 True 4 False dtype: bool 删除缺失值: 0 10.0 2 30.0 4 50.0 dtype: float64 使用0填充缺失值: 0 10.0 1 0.0 2 30.0 3 0.0 4 50.0 dtype: float64

4.2 DataFrame 常用方法

4.2.1 查看数据方法

in1

复制代码

import pandas as pd df = pd.DataFrame({ "姓名": ["张三", "李四", "王五"], "年龄": [20, 21, 22], "成绩": [95, 88, 76] }) print("查看前2行:") print(df.head(2)) print("\n查看数据信息:") print(df.info()) print("\n查看统计信息:") print(df.describe())

out1

复制代码

查看前2行: 姓名 年龄 成绩 0 张三 20 95 1 李四 21 88 查看数据信息: <class 'pandas.core.frame.DataFrame'> RangeIndex: 3 entries, 0 to 2 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 姓名 3 non-null object 1 年龄 3 non-null int64 2 成绩 3 non-null int64 dtypes: int64(2), object(1) memory usage: 200.0+ bytes None 查看统计信息: 年龄 成绩 count 3.0 3.000000 mean 21.0 86.333333 std 1.0 9.609024 min 20.0 76.000000 25% 20.5 82.000000 50% 21.0 88.000000 75% 21.5 91.500000 max 22.0 95.000000

4.2.2 排序方法

in2

复制代码

print("按成绩排序:") print(df.sort_values(by="成绩")) print("\n按成绩降序排序:") print(df.sort_values(by="成绩", ascending=False))

out2

复制代码

按成绩排序: 姓名 年龄 成绩 2 王五 22 76 1 李四 21 88 0 张三 20 95 按成绩降序排序: 姓名 年龄 成绩 0 张三 20 95 1 李四 21 88 2 王五 22 76

4.2.3 缺失值处理

in3

复制代码

import pandas as pd import numpy as np # 创建包含缺失值的 DataFrame df = pd.DataFrame({ "姓名": ["张三", "李四", "王五", None], "年龄": [20, np.nan, 22, 21], "成绩": [95, 88, np.nan, 90] }) print("原始数据:") print(df) # 1. 判断缺失值 print("\n判断缺失值:") print(df.isnull()) # 2. 删除缺失值所在行 print("\n删除缺失值后的数据:") print(df.dropna()) # 3. 填充缺失值 print("\n使用 0 填充缺失值:") print(df.fillna(0))

out3

复制代码

原始数据: 姓名 年龄 成绩 0 张三 20.0 95.0 1 李四 NaN 88.0 2 王五 22.0 NaN 3 None 21.0 90.0 判断缺失值: 姓名 年龄 成绩 0 False False False 1 False True False 2 False False True 3 True False False 删除缺失值后的数据: 姓名 年龄 成绩 0 张三 20.0 95.0 使用 0 填充缺失值: 姓名 年龄 成绩 0 张三 20.0 95.0 1 李四 0.0 88.0 2 王五 22.0 0.0 3 0 21.0 90.0

4.2.4 apply() 函数

in4

复制代码

import pandas as pd df = pd.DataFrame({ "姓名": ["张三", "李四", "王五"], "年龄": [20, 21, 22], "成绩": [95, 88, 76] }) df["成绩等级"] = df["成绩"].apply( lambda x: "优秀" if x >= 90 else "良好" ) print(df)

out4

复制代码

姓名 年龄 成绩 成绩等级 0 张三 20 95 优秀 1 李四 21 88 良好 2 王五 22 76 良好

4.2.5 数据类型转换
4.2.5.1 查看数据类型

in1

复制代码

import pandas as pd df = pd.DataFrame({ "姓名": ["张三", "李四"], "年龄": ["20", "21"], "成绩": ["95", "88"] }) print(df.dtypes)

out1

复制代码

姓名 object 年龄 object 成绩 object dtype: object

4.2.5.2 astype() 类型转换

in2

复制代码

df["年龄"] = df["年龄"].astype(int) df["成绩"] = df["成绩"].astype(float) print(df) print(df.dtypes)

out2

复制代码

姓名 年龄 成绩 0 张三 20 95.0 1 李四 21 88.0 姓名 object 年龄 int64 成绩 float64 dtype: object

4.2.5.3 to_numeric() 数值转换

in3

复制代码

df = pd.DataFrame({ "成绩": ["95", "88", "缺考"] }) df["成绩"] = pd.to_numeric( df["成绩"], errors="coerce" ) print(df)

out3

复制代码

成绩 0 95.0 1 88.0 2 NaN

4.2.5.4 to_datetime() 日期转换

in4

复制代码

df = pd.DataFrame({ "日期": ["2025-01-01", "2025-02-15"] }) df["日期"] = pd.to_datetime(df["日期"]) print(df) print(df.dtypes)

out4

复制代码

日期 0 2025-01-01 1 2025-02-15 日期 datetime64[ns] dtype: object

4.2.6 去重方法

in6

复制代码

import pandas as pd df = pd.DataFrame({ "姓名": ["张三", "李四", "张三", "王五", "李四"], "年龄": [20, 21, 20, 22, 21], "班级": ["一班", "二班", "一班", "三班", "二班"] }) print("原始DataFrame:") print(df) print("\n姓名列唯一值:") print(df["姓名"].unique()) print("\n姓名列唯一值个数:") print(df["姓名"].nunique()) print("\n删除重复行:") print(df.drop_duplicates()) print("\n按姓名去重(保留第一次出现):") print(df.drop_duplicates(subset=["姓名"])) print("\n按姓名去重(保留最后一次出现):") print(df.drop_duplicates(subset=["姓名"], keep="last"))

out4

复制代码

原始DataFrame: 姓名 年龄 班级 0 张三 20 一班 1 李四 21 二班 2 张三 20 一班 3 王五 22 三班 4 李四 21 二班 姓名列唯一值: ['张三' '李四' '王五'] 姓名列唯一值个数: 3 删除重复行: 姓名 年龄 班级 0 张三 20 一班 1 李四 21 二班 3 王五 22 三班 按姓名去重(保留第一次出现): 姓名 年龄 班级 0 张三 20 一班 1 李四 21 二班 3 王五 22 三班 按姓名去重(保留最后一次出现): 姓名 年龄 班级 2 张三 20 一班 3 王五 22 三班 4 李四 21 二班

5. Pandas 的变形操作

5.1 转置操作

实操:DataFrame 转置操作

in1

复制代码

# 导入所需库,创建示例DataFrame import pandas as pd import numpy as np # 创建学生成绩表(行:学生,列:科目) data = { "语文": [88, 92, 85, 90], "数学": [95, 89, 93, 87], "英语": [92, 88, 90, 94] } df = pd.DataFrame(data, index=["张三", "李四", "王五", "赵六"]) print("转置前的DataFrame(行:学生,列:科目):") print(df) # 转置操作:.T df_transpose = df.T print("\n转置后的DataFrame(行:科目,列:学生):") print(df_transpose)

out1

复制代码

转置前的DataFrame(行:学生,列:科目): 语文 数学 英语 张三 88 95 92 李四 92 89 88 王五 85 93 90 赵六 90 87 94 转置后的DataFrame(行:科目,列:学生): 张三 李四 王五 赵六 语文 88 92 85 90 数学 95 89 93 87 英语 92 88 90 94

5.2 重塑操作

5.2.1 宽转长:melt()方法

实操:melt()宽转长

in1

复制代码

# 导入所需库,创建宽格式DataFrame import pandas as pd data = { "姓名": ["张三", "李四", "王五"], "语文": [88, 92, 85], "数学": [95, 89, 93], "英语": [92, 88, 90] } df_wide = pd.DataFrame(data) print("宽格式DataFrame:") print(df_wide) # 宽转长:保留"姓名",将"语文、数学、英语"重塑为"科目-成绩" df_long = df_wide.melt( id_vars=["姓名"], # 保留的列 value_vars=["语文", "数学", "英语"], # 要重塑的列 var_name="科目", # 特征列名称 value_name="成绩" # 值列名称 ) print("\n长格式DataFrame:") print(df_long)

out1

复制代码

宽格式DataFrame: 姓名 语文 数学 英语 0 张三 88 95 92 1 李四 92 89 88 2 王五 85 93 90 长格式DataFrame: 姓名 科目 成绩 0 张三 语文 88 1 李四 语文 92 2 王五 语文 85 3 张三 数学 95 4 李四 数学 89 5 王五 数学 93 6 张三 英语 92 7 李四 英语 88 8 王五 英语 90

5.2.2 长转宽:pivot()方法

实操:pivot()长转宽

in2

复制代码

# 沿用上面的长格式DataFrame(df_long) print("长格式DataFrame:") print(df_long) # 长转宽:以"姓名"为行索引,"科目"为列索引,"成绩"为值 df_wide2 = df_long.pivot( index="姓名", columns="科目", values="成绩" ) print("\n长转宽后的DataFrame:") print(df_wide2)

out2

复制代码

宽格式DataFrame: 姓名 语文 数学 英语 0 张三 88 95 92 1 李四 92 89 88 2 王五 85 93 90 长格式DataFrame: 姓名 科目 成绩 0 张三 语文 88 1 李四 语文 92 2 王五 语文 85 3 张三 数学 95 4 李四 数学 89 5 王五 数学 93 6 张三 英语 92 7 李四 英语 88 8 王五 英语 90 长转宽后的DataFrame: 科目 数学 英语 语文 姓名 张三 95 92 88 李四 89 88 92 王五 93 90 85

5.2.3 对数据的重塑(剔除/新增 Series)

一、剔除 Series(删除列)

实操1:剔除Series(删除列)

in1

复制代码

import pandas as pd # 构造数据 data = { "姓名": ["张三", "李四", "王五", "赵六"], "语文": [88, 92, 85, 90], "数学": [95, 89, 93, 87], "英语": [92, 88, 90, 85], "备注": ["无", "无", "无", "临时数据"] } df_wide = pd.DataFrame(data) print("原始DataFrame") print(df_wide) # 1. 删除列(剔除冗余Series) df_step1 = df_wide.drop(columns=["备注"]) print("\n删除备注列") print(df_step1) # 2. 删除多列(扩展剔除) df_step2 = df_step1.drop(columns=["英语"]) print("\n再删除英语列") print(df_step2) # 3. inplace原地修改演示 df_copy = df_wide.copy() df_copy.drop(columns=["备注"], inplace=True) print("\ninplace=True 后原地修改") print(df_copy) # 4. errors容错演示 df_error_demo = df_wide.drop(columns=["不存在的列"], errors="ignore") print("\nerrors='ignore' 演示(不报错)") print(df_error_demo)

out1

复制代码

原始DataFrame 姓名 语文 数学 英语 备注 0 张三 88 95 92 无 1 李四 92 89 88 无 2 王五 85 93 90 无 3 赵六 90 87 85 临时数据 删除备注列 姓名 语文 数学 英语 0 张三 88 95 92 1 李四 92 89 88 2 王五 85 93 90 3 赵六 90 87 85 再删除英语列 姓名 语文 数学 0 张三 88 95 1 李四 92 89 2 王五 85 93 3 赵六 90 87 inplace=True 后原地修改 姓名 语文 数学 英语 0 张三 88 95 92 1 李四 92 89 88 2 王五 85 93 90 3 赵六 90 87 85 errors='ignore' 演示(不报错) 姓名 语文 数学 英语 备注 0 张三 88 95 92 无 1 李四 92 89 88 无 2 王五 85 93 90 无 3 赵六 90 87 85 临时数据

二、新增Series(添加DataFrame列)

实操2:直接赋值新增Series(简单衍生列)

in2

复制代码

import pandas as pd # 构造数据 data = { "姓名": ["张三", "李四", "王五", "赵六"], "语文": [88, 92, 85, 90], "数学": [95, 89, 93, 87], "英语": [92, 88, 90, 85], "备注": ["无", "无", "无", "临时数据"] } df_wide = pd.DataFrame(data) print("原始DataFrame") print(df_wide) # 1. 删除列(剔除冗余Series) df_step1 = df_wide.drop(columns=["备注"]) print("\n删除备注列") print(df_step1) df_reshape_add1 = df_step1.copy() # 新增"平均分"列(Series),计算三科平均分 df_reshape_add1["平均分"] = ( df_reshape_add1["语文"] + df_reshape_add1["数学"] + df_reshape_add1["英语"] ) / 3 print("新增Series(平均分)后的DataFrame:") print(df_reshape_add1)

out2

复制代码

原始DataFrame 姓名 语文 数学 英语 备注 0 张三 88 95 92 无 1 李四 92 89 88 无 2 王五 85 93 90 无 3 赵六 90 87 85 临时数据 删除备注列 姓名 语文 数学 英语 0 张三 88 95 92 1 李四 92 89 88 2 王五 85 93 90 3 赵六 90 87 85 新增Series(平均分)后的DataFrame: 姓名 语文 数学 英语 平均分 0 张三 88 95 92 91.666667 1 李四 92 89 88 89.666667 2 王五 85 93 90 89.333333 3 赵六 90 87 85 87.333333

实操3:assign()方法新增Series(多列批量新增)

in3

复制代码

# 沿用df_reshape_add1,使用assign()新增多列Series(等级、是否及格) df_reshape_add2 = df_reshape_add1.assign( 等级=lambda x: pd.cut( x["平均分"], bins=[0, 60, 80, 90, 100], labels=["不及格", "及格", "良好", "优秀"] ), 是否及格=lambda x: x["平均分"] >= 60 # 布尔型Series ) print("assign()新增多列Series后的DataFrame:") print(df_reshape_add2)

out3

复制代码

assign()新增多列Series后的DataFrame: 姓名 语文 数学 英语 平均分 等级 是否及格 0 张三 88 95 92 91.666667 优秀 True 1 李四 92 89 88 89.666667 良好 True 2 王五 85 93 90 89.333333 良好 True 3 赵六 90 87 85 87.333333 良好 True

5.2.4 分列操作(字符串拆分)

实操1:基础分列操作

in1

复制代码

# 导入所需库 import pandas as pd # 创建包含复合信息的DataFrame df = pd.DataFrame({ "学生信息": ["张三-一班", "李四-二班", "王五-三班"] }) print("分列前的数据:") print(df) # 按 "-" 拆分,并展开为多列 df_split = df["学生信息"].str.split("-", expand=True) # 修改列名 df_split.columns = ["姓名", "班级"] print("\n分列后的数据:") print(df_split)

out1

复制代码

分列前的数据: 学生信息 0 张三-一班 1 李四-二班 2 王五-三班 分列后的数据: 姓名 班级 0 张三 一班 1 李四 二班 2 王五 三班

实操2:分列后合并回原DataFrame

in2

复制代码

# 将拆分后的列拼接回原DataFrame df_result = pd.concat([df, df_split], axis=1) print("分列并合并后的DataFrame:") print(df_result)

out2

复制代码

分列并合并后的DataFrame: 学生信息 姓名 班级 0 张三-一班 张三 一班 1 李四-二班 李四 二班 2 王五-三班 王五 三班

5.2.5 合并操作(merge)

实操1:内连接(inner)

in1

复制代码

import pandas as pd # 学生基本信息表 df_student = pd.DataFrame({ "学号": [1001, 1002, 1003], "姓名": ["张三", "李四", "王五"] }) # 学生成绩表 df_score = pd.DataFrame({ "学号": [1001, 1002, 1004], "数学": [95, 88, 90] }) print("学生信息表:") print(df_student) print("\n学生成绩表:") print(df_score) # 内连接 df_merge_inner = pd.merge( df_student, df_score, on="学号", how="inner" ) print("\ninner内连接结果:") print(df_merge_inner)

out1

复制代码

学生信息表: 学号 姓名 0 1001 张三 1 1002 李四 2 1003 王五 学生成绩表: 学号 数学 0 1001 95 1 1002 88 2 1004 90 inner内连接结果: 学号 姓名 数学 0 1001 张三 95 1 1002 李四 88

实操2:左连接(left)

in2

复制代码

# 左连接:保留左表全部数据 df_merge_left = pd.merge( df_student, df_score, on="学号", how="left" ) print("left左连接结果:") print(df_merge_left)

out2

复制代码

left左连接结果: 学号 姓名 数学 0 1001 张三 95.0 1 1002 李四 88.0 2 1003 王五 NaN

实操3:外连接(outer)

in3

复制代码

# 外连接:保留所有数据 df_merge_outer = pd.merge( df_student, df_score, on="学号", how="outer" ) print("outer外连接结果:") print(df_merge_outer)

out3

复制代码

outer外连接结果: 学号 姓名 数学 0 1001 张三 95.0 1 1002 李四 88.0 2 1003 王五 NaN 3 1004 NaN 90.0

5.3 拼接操作

5.3.1 纵向拼接(axis=0)

实操1:纵向拼接

in1

复制代码

# 导入所需库,创建两个同结构的DataFrame(班级1、班级2成绩表) import pandas as pd # 班级1成绩表 df1 = pd.DataFrame({ "姓名": ["张三", "李四"], "科目": ["语文", "数学"], "成绩": [88, 95] }) # 班级2成绩表 df2 = pd.DataFrame({ "姓名": ["王五", "赵六"], "科目": ["英语", "语文"], "成绩": [92, 85] }) print("班级1成绩表:") print(df1) print("\n班级2成绩表:") print(df2) # 纵向拼接(axis=0),重置索引 df_concat_v = pd.concat([df1, df2], axis=0, ignore_index=True) print("\n纵向拼接后的成绩表:") print(df_concat_v)

out1

复制代码

班级1成绩表: 姓名 科目 成绩 0 张三 语文 88 1 李四 数学 95 班级2成绩表: 姓名 科目 成绩 0 王五 英语 92 1 赵六 语文 85 纵向拼接后的成绩表: 姓名 科目 成绩 0 张三 语文 88 1 李四 数学 95 2 王五 英语 92 3 赵六 语文 85

实操2:纵向拼接(join=outer,列结构不一致,自动NaN填充)

in2

复制代码

# 创建列结构不一致的DataFrame(班级3成绩表多了"班级"列) df3 = pd.DataFrame({ "姓名": ["孙七", "周八"], "科目": ["数学", "英语"], "成绩": [90, 87], "班级": ["三班", "三班"] # 班级3多的列 }) print("班级3成绩表(多一列'班级'):") print(df3) # 纵向拼接(axis=0,join=outer,列结构不一致) df_concat_v_outer = pd.concat([df1, df3], axis=0, ignore_index=True, join="outer") print("\n纵向拼接(outer,列结构不一致)后的成绩表(NaN填充缺失值):") print(df_concat_v_outer)

out2

复制代码

班级3成绩表(多一列'班级'): 姓名 科目 成绩 班级 0 孙七 数学 90 三班 1 周八 英语 87 三班 纵向拼接(outer,列结构不一致)后的成绩表(NaN填充缺失值): 姓名 科目 成绩 班级 0 张三 语文 88 NaN 1 李四 数学 95 NaN 2 孙七 数学 90 三班 3 周八 英语 87 三班

实操3:纵向拼接(join=inner,列结构不一致,只保留共同列)

in3

复制代码

# 沿用班级1(df1)和班级3(df3)的DataFrame,使用inner连接纵向拼接 print("班级1成绩表(无班级列):") print(df1) print("\n班级3成绩表(有班级列):") print(df3) # 纵向拼接(axis=0,join=inner,列结构不一致) df_concat_v_inner = pd.concat([df1, df3], axis=0, ignore_index=True, join="inner") print("\n纵向拼接(inner,列结构不一致)后的成绩表(只保留共同列):") print(df_concat_v_inner)

out3

复制代码

班级1成绩表(无班级列): 姓名 科目 成绩 0 张三 语文 88 1 李四 数学 95 班级3成绩表(有班级列): 姓名 科目 成绩 班级 0 孙七 数学 90 三班 1 周八 英语 87 三班 纵向拼接(inner,列结构不一致)后的成绩表(只保留共同列): 姓名 科目 成绩 0 张三 语文 88 1 李四 数学 95 2 孙七 数学 90 3 周八 英语 87

5.3.2 横向拼接(axis=1)

实操1:横向拼接

in1

复制代码

# 导入所需库,创建两个同索引的DataFrame(学生基本信息+成绩) import pandas as pd # 学生基本信息表(行索引:学生姓名) df_info = pd.DataFrame({ "年龄": [20, 19, 21], "性别": ["男", "女", "男"] }, index=["张三", "李四", "王五"]) # 学生成绩表(行索引:学生姓名) df_score = pd.DataFrame({ "语文": [88, 92, 85], "数学": [95, 89, 93] }, index=["张三", "李四", "王五"]) print("学生基本信息表:") print(df_info) print("\n学生成绩表:") print(df_score) # 横向拼接(axis=1),内连接(只保留共同索引) df_concat_h = pd.concat([df_info, df_score], axis=1, join="inner") print("\n横向拼接后的学生信息+成绩表:") print(df_concat_h)

out1

复制代码

学生基本信息表: 年龄 性别 张三 20 男 李四 19 女 王五 21 男 学生成绩表: 语文 数学 张三 88 95 李四 92 89 王五 85 93 横向拼接后的学生信息+成绩表: 年龄 性别 语文 数学 张三 20 男 88 95 李四 19 女 92 89 王五 21 男 85 93

补充实操2:横向拼接(join=outer,索引不一致,自动NaN填充)

in2

复制代码

# 索引不一致的成绩表 df_score2 = pd.DataFrame({ "语文": [80, 91, 86], "数学": [70, 80, 91] }, index=["张三", "李四", "赵六"]) print("新的学生成绩表(索引与基本信息表不一致):") print(df_score2) # 横向拼接(外连接) df_concat_h_outer = pd.concat([df_info, df_score2], axis=1, join="outer") print("\n横向拼接(outer,索引不一致)后的表格(NaN填充缺失值):") print(df_concat_h_outer)

out2

复制代码

新的学生成绩表(索引与基本信息表不一致): 语文 数学 张三 80 70 李四 91 80 赵六 86 91 横向拼接(outer,索引不一致)后的表格(NaN填充缺失值): 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0

6. 缺失值操作

6.1 找到缺失值

实操1:查看缺失值位置(isnull())

in1

复制代码

# 导入所需库,创建含缺失值的DataFrame import pandas as pd import numpy as np # 模拟含缺失值的学生信息+成绩表 data = { "年龄": [20.0, 19.0, 21.0, np.nan], "性别": ["男", "女", "男", np.nan], "语文": [80.0, 91.0, np.nan, 86.0], "数学": [70.0, 80.0, np.nan, 91.0] } df_missing = pd.DataFrame(data, index=["张三", "李四", "王五", "赵六"]) print("含缺失值的DataFrame:") print(df_missing) # 查看缺失值位置(isnull()) print("\n缺失值位置(True=缺失值):") print(df_missing.isna())

out1

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 缺失值位置(True=缺失值): 年龄 性别 语文 数学 张三 False False False False 李四 False False False False 王五 False False True True 赵六 True True False False

实操2:统计每列缺失值数量(isnull() + sum())

in2

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("含缺失值的DataFrame:") print(df_missing) # 统计每列缺失值数量(默认axis=0,按列统计) print("\n每列缺失值数量:") print(df_missing.isnull().sum())

out2

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 每列缺失值数量: 年龄 1 性别 1 语文 1 数学 1 dtype: int64

实操3:统计每行缺失值数量(isnull() + sum(axis=1))

in3

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("含缺失值的DataFrame:") print(df_missing) # 统计每行缺失值数量(按行统计) print("\n每行缺失值数量:") print(df_missing.isnull().sum(axis=1))

out3

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 每行缺失值数量: 张三 0 李四 0 王五 2 赵六 2 dtype: int64

实操4:查看有效数据位置(notnull())

in4

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("含缺失值的DataFrame:") print(df_missing) # 查看有效数据位置(notnull()) print("\n有效数据位置(True=有效数据):") print(df_missing.notnull())

out4

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 有效数据位置(True=有效数据): 年龄 性别 语文 数学 张三 True True True True 李四 True True True True 王五 True True False False 赵六 False False True True

实操5:筛选含缺失值的行(any(axis=1))

in5

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("含缺失值的DataFrame:") print(df_missing) # 筛选出含缺失值的行(至少有1个缺失值) print("\n含缺失值的行:") print(df_missing[df_missing.isnull().any(axis=1)])

out5

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 含缺失值的行: 年龄 性别 语文 数学 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0

6.2 删除缺失值

实操1:删除含缺失值的行(默认axis=0, how=any)

in1

复制代码

# 导入所需库,创建含缺失值的DataFrame import pandas as pd import numpy as np # 模拟含缺失值的学生信息+成绩表 data = { "年龄": [20.0, 19.0, 21.0, np.nan], "性别": ["男", "女", "男", np.nan], "语文": [80.0, 91.0, np.nan, 86.0], "数学": [70.0, 80.0, np.nan, 91.0] } df_missing = pd.DataFrame(data, index=["张三", "李四", "王五", "赵六"]) print("含缺失值的DataFrame:") print(df_missing) # 删除含缺失值的行(默认axis=0, how=any) df_drop1 = df_missing.dropna() print("\n删除所有含缺失值的行(仅保留无缺失值的行):") print(df_drop1)

out1

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 删除所有含缺失值的行(仅保留无缺失值的行): 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0

实操2:删除所有值都是缺失值的行(how=all)

in2

复制代码

# 沿用含缺失值的DataFrame(df_missing) # 新增一行全缺失值数据 df_missing2 = df_missing.copy() df_missing2.loc["孙七"] = np.nan print("新增全缺失值行后的DataFrame:") print(df_missing2) # 删除全缺失值的行(how=all) df_drop2 = df_missing2.dropna(how="all") print("\n删除全缺失值的行(保留非全缺失的行):") print(df_drop2)

out2

复制代码

新增全缺失值行后的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 孙七 NaN NaN NaN NaN 删除全缺失值的行(保留非全缺失的行): 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0

实操3:按阈值保留行(thresh=3)

in3

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 按阈值保留行(thresh=3:至少有3个有效数据才保留) df_drop3 = df_missing.dropna(thresh=3) print("\n至少有3个有效数据的行(保留):") print(df_drop3)

out3

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 至少有3个有效数据的行(保留): 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0

实操4:指定列检查缺失值(subset)

in4

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 指定列检查缺失值(subset:仅检查"语文"和"数学"列) df_drop4 = df_missing.dropna(subset=["语文", "数学"]) print('\n仅删除"语文"/"数学"列有缺失值的行:') print(df_drop4)

out4

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 仅删除"语文"/"数学"列有缺失值的行: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 赵六 NaN NaN 86.0 91.0

实操5:删除含缺失值的列(axis=1)

in5

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 删除含缺失值的列(axis=1) df_drop5 = df_missing.dropna(axis=1) print("\n删除所有含缺失值的列(所有列都包含缺失值,因此结果为空DataFrame):") print(df_drop5)

out5

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 删除所有含缺失值的列(无符合条件的列,保留所有列): Empty DataFrame Columns: [] Index: [张三, 李四, 王五, 赵六]

6.3 填充缺失值

实操1:固定值填充(用0填充所有缺失值)

in1

复制代码

# 导入所需库,创建含缺失值的DataFrame import pandas as pd import numpy as np # 模拟含缺失值的学生信息+成绩表 data = { "年龄": [20.0, 19.0, 21.0, np.nan], "性别": ["男", "女", "男", np.nan], "语文": [80.0, 91.0, np.nan, 86.0], "数学": [70.0, 80.0, np.nan, 91.0] } df_missing = pd.DataFrame(data, index=["张三", "李四", "王五", "赵六"]) print("含缺失值的DataFrame:") print(df_missing) # 固定值填充(用0填充所有缺失值) df_fill1 = df_missing.fillna(value=0) print("\n用0填充所有缺失值:") print(df_fill1)

out1

复制代码

含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 用0填充所有缺失值: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 0.0 0.0 赵六 0.0 0 86.0 91.0

实操2:数值型用均值、分类型用众数填充

in2

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 数值型列用均值填充,分类型列用众数填充 # 计算各列填充值 fill_values = { "年龄": df_missing["年龄"].mean(), # 数值型:均值 "性别": df_missing["性别"].mode()[0], # 分类型:众数(取第一个众数) "语文": df_missing["语文"].mean(), "数学": df_missing["数学"].mean() } df_fill2 = df_missing.fillna(value=fill_values) print("\n数值型用均值、分类型用众数填充:") print(df_fill2)

out2

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 数值型用均值、分类型用众数填充: 年龄 性别 语文 数学 张三 20.0 男 80.000000 70.000000 李四 19.0 女 91.000000 80.000000 王五 21.0 男 85.666667 80.333333 赵六 20.0 男 86.000000 91.000000

实操3:向前填充(ffill)

in3

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 向前填充(ffill:用前一行有效数据填充) df_fill3 = df_missing.ffill() print("\n向前填充(ffill):") print(df_fill3)

out3

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 向前填充(ffill): 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 91.0 80.0 赵六 21.0 男 86.0 91.0

实操4:向后填充(bfill)

in4

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 向后填充(bfill:用后一行有效数据填充) df_fill4 = df_missing.bfill() print("\n向后填充(bfill):") print(df_fill4)

out4

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 向后填充(bfill): 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 86.0 91.0 赵六 NaN NaN 86.0 91.0

实操5:向前填充,限制填充次数(limit=1)

in5

复制代码

#为了更好的展示填充次数限制,这里多加了一个NaN df_copy = df_missing.copy() df_copy.loc["李四", "语文"] = np.nan print("为了演示而修改后的DataFrame:") print(df_copy) # 在每一列中,最多连续向前填充 1 个缺失值 df_fill5 = df_copy.ffill(limit=1) print("\n向前填充,限制连续填充1次:") print(df_fill5)

out5

复制代码

为了演示而修改后的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 NaN 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 向前填充,限制连续填充1次: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 80.0 80.0 王五 21.0 男 NaN 80.0 赵六 21.0 男 86.0 91.0

实操6:直接修改原数据(inplace=True)

in6

复制代码

# 沿用含缺失值的DataFrame(df_missing) print("原始含缺失值的DataFrame:") print(df_missing) # 直接修改原数据(inplace=True) df_missing_copy = df_missing.copy() fill_values = { "年龄": df_missing["年龄"].mean(), "性别": df_missing["性别"].mode()[0], "语文": df_missing["语文"].mean(), "数学": df_missing["数学"].mean() } df_missing_copy.fillna(value=fill_values, inplace=True) print("\n直接修改原数据(inplace=True):") print(df_missing_copy)

out6

复制代码

原始含缺失值的DataFrame: 年龄 性别 语文 数学 张三 20.0 男 80.0 70.0 李四 19.0 女 91.0 80.0 王五 21.0 男 NaN NaN 赵六 NaN NaN 86.0 91.0 直接修改原数据(inplace=True): 年龄 性别 语文 数学 张三 20.000000 男 80.000000 70.000000 李四 19.000000 女 91.000000 80.000000 王五 21.000000 男 85.666667 80.333333 赵六 20.000000 男 86.000000 91.000000

7. 数据分箱

7.1 固定区间分箱:cut()方法

实操1:成绩等级划分

in1

复制代码

# 导入所需库 import pandas as pd # 创建学生成绩Series score = pd.Series([95, 82, 76, 61, 58, 89, 92]) print("原始成绩数据:") print(score) # 使用cut()进行固定区间分箱 score_level = pd.cut( score, bins=[0, 60, 80, 90, 100], labels=["不及格", "及格", "良好", "优秀"] ) print("\n分箱后的成绩等级:") print(score_level)

out1

复制代码

原始成绩数据: 0 95 1 82 2 76 3 61 4 58 5 89 6 92 dtype: int64 分箱后的成绩等级: 0 优秀 1 良好 2 及格 3 及格 4 不及格 5 良好 6 优秀 dtype: category Categories (4, object): ['不及格' < '及格' < '良好' < '优秀']

7.2 自动等宽分箱

实操1:自动划分为4个区间

in1

复制代码

import pandas as pd # 创建数据 data = pd.Series([12, 25, 36, 48, 59, 63, 77, 85, 91]) print("原始数据:") print(data) # 自动等宽分为4组 bins_result = pd.cut(data, bins=4) print("\n等宽分箱结果:") print(bins_result)

out1

复制代码

原始数据: 0 12 1 25 2 36 3 48 4 59 5 63 6 77 7 85 8 91 dtype: int64 等宽分箱结果: 0 (11.921, 31.75] 1 (11.921, 31.75] 2 (31.75, 51.5] 3 (31.75, 51.5] 4 (51.5, 71.25] 5 (51.5, 71.25] 6 (71.25, 91.0] 7 (71.25, 91.0] 8 (71.25, 91.0] dtype: category

7.3 分位数分箱:qcut()方法

实操1:按四分位数分箱

in1

复制代码

import pandas as pd # 创建数据 data = pd.Series([10, 15, 20, 30, 35, 40, 60, 80, 100, 120]) print("原始数据:") print(data) # 按四分位数分箱 qcut_result = pd.qcut( data, q=4, labels=["第一档", "第二档", "第三档", "第四档"] ) print("\nqcut分箱结果:") print(qcut_result)

out1

复制代码

原始数据: 0 10 1 15 2 20 3 30 4 35 5 40 6 60 7 80 8 100 9 120 dtype: int64 qcut分箱结果: 0 第一档 1 第一档 2 第一档 3 第二档 4 第二档 5 第三档 6 第三档 7 第四档 8 第四档 9 第四档 dtype: category

7.4 分箱结果统计

实操1:统计各分箱中的数据量

in1

复制代码

import pandas as pd # 创建数据 score = pd.Series([95, 82, 76, 61, 58, 89, 92, 45, 73, 84]) # 分箱 score_level = pd.cut( score, bins=[0, 60, 80, 90, 100], labels=["不及格", "及格", "良好", "优秀"] ) # 统计各分箱数量 count_result = score_level.value_counts().sort_index() print("各分箱中的数据数量:") print(count_result)

out1

复制代码

各分箱中的数据数量: 不及格 2 及格 2 良好 3 优秀 3 dtype: int64

8. Pandas 中的运算

8.1 对象和常数的运算

实操1:Series 与常数的加减乘除运算

in1

复制代码

# 导入所需库,创建Series对象 import pandas as pd import numpy as np # 模拟学生语文成绩Series score_Chinese = pd.Series([80, 91, 86, 78], index=["张三", "李四", "赵六", "孙七"]) print("原始语文成绩Series:") print(score_Chinese) # Series与常数的加减乘除运算 print("\n1. 加常数(每人加5分):") print(score_Chinese + 5) print("\n2. 减常数(每人减2分):") print(score_Chinese - 2) print("\n3. 乘常数(成绩缩放2倍):") print(score_Chinese * 2) print("\n4. 除常数(成绩除以10):") print(score_Chinese / 10)

out1

复制代码

原始语文成绩Series: 张三 80 李四 91 赵六 86 孙七 78 dtype: int64 1. 加常数(每人加5分): 张三 85 李四 96 赵六 91 孙七 83 dtype: int64 2. 减常数(每人减2分): 张三 78 李四 89 赵六 84 孙七 76 dtype: int64 3. 乘常数(成绩缩放2倍): 张三 160 李四 182 赵六 172 孙七 156 dtype: int64 4. 除常数(成绩除以10): 张三 8.0 李四 9.1 赵六 8.6 孙七 7.8 dtype: float64

实操2:DataFrame与常数的运算(含幂运算)

in2

复制代码

# 模拟学生成绩DataFrame data = { "语文": [80, 91, 86, 78], "数学": [70, 80, 91, 85], "英语": [85, 79, 88, 92] } df_score = pd.DataFrame(data, index=["张三", "李四", "赵六", "孙七"]) print("原始成绩DataFrame:") print(df_score) # DataFrame与常数的运算 print("\n1. 加常数(每科成绩加3分):") print(df_score + 3) print("\n2. 乘常数(成绩缩放1.2倍):") print(df_score * 1.2) print("\n3. 幂运算(每科成绩求平方):") print(df_score ** 2)

out2

复制代码

原始成绩DataFrame: 语文 数学 英语 张三 80 70 85 李四 91 80 79 赵六 86 91 88 孙七 78 85 92 1. 加常数(每科成绩加3分): 语文 数学 英语 张三 83 73 88 李四 94 83 82 赵六 89 94 91 孙七 81 88 95 2. 乘常数(成绩缩放1.2倍): 语文 数学 英语 张三 96.0 84.0 102.0 李四 109.2 96.0 94.8 赵六 103.2 109.2 105.6 孙七 93.6 102.0 110.4 3. 幂运算(每科成绩求平方): 语文 数学 英语 张三 6400 4900 7225 李四 8281 6400 6241 赵六 7396 8281 7744 孙七 6084 7225 8464

8.2 对象和对象的运算

实操1:Series 与 Series 的运算(同索引、不同索引)

in1

复制代码

# 导入所需库,创建两个Series对象 import pandas as pd import numpy as np # 同索引Series(第一次、第二次语文成绩) score1 = pd.Series([80, 91, 86, 78], index=["张三", "李四", "赵六", "孙七"]) score2 = pd.Series([85, 89, 90, 82], index=["张三", "李四", "赵六", "孙七"]) # 不同索引Series(新增学生王五) score3 = pd.Series([75, 88], index=["王五", "赵六"]) print("第一次语文成绩:") print(score1) print("\n第二次语文成绩:") print(score2) print("\n新增学生成绩:") print(score3) # 同索引Series运算(两次成绩差值) print("\n1. 同索引运算(第二次 - 第一次成绩):") print(score2 - score1) # 不同索引Series运算(score1与score3求和) print("\n2. 不同索引运算(score1 + score3):") print(score1 + score3)

out1

复制代码

第一次语文成绩: 张三 80 李四 91 赵六 86 孙七 78 dtype: int64 第二次语文成绩: 张三 85 李四 89 赵六 90 孙七 82 dtype: int64 新增学生成绩: 王五 75 赵六 88 dtype: int64 1. 同索引运算(第二次 - 第一次成绩): 张三 5 李四 -2 赵六 4 孙七 4 dtype: int64 2. 不同索引运算(score1 + score3): 孙七 NaN 张三 NaN 李四 NaN 王五 NaN 赵六 174.0 dtype: float64

实操2:DataFrame 与 DataFrame 的运算(同结构、不同结构)

in2

复制代码

# 同结构DataFrame(第一次、第二次考试成绩) data1 = { "语文": [80, 91, 86, 78], "数学": [70, 80, 91, 85] } df1 = pd.DataFrame(data1, index=["张三", "李四", "赵六", "孙七"]) data2 = { "语文": [85, 89, 90, 82], "数学": [75, 82, 88, 89] } df2 = pd.DataFrame(data2, index=["张三", "李四", "赵六", "孙七"]) # 不同结构DataFrame(新增英语成绩,新增王五) data3 = { "语文": [75, 88, 92], "英语": [80, 85, 90] } df3 = pd.DataFrame(data3, index=["王五", "赵六", "孙七"]) print("第一次考试成绩:") print(df1) print("\n第二次考试成绩:") print(df2) print("\n新增成绩数据:") print(df3) # 同结构DataFrame运算(两次成绩求和) print("\n1. 同结构运算(两次成绩求和):") print(df1 + df2) # 不同结构DataFrame运算(df1与df3求差) print("\n2. 不同结构运算(df1 - df3):") print(df1 - df3)

out2

复制代码

第一次考试成绩: 语文 数学 张三 80 70 李四 91 80 赵六 86 91 孙七 78 85 第二次考试成绩: 语文 数学 张三 85 75 李四 89 82 赵六 90 88 孙七 82 89 新增成绩数据: 语文 英语 王五 75 80 赵六 88 85 孙七 92 90 1. 同结构运算(两次成绩求和): 语文 数学 张三 165 145 李四 180 162 赵六 176 179 孙七 160 174 2. 不同结构运算(df1 - df3): 数学 英语 语文 孙七 NaN NaN -14.0 张三 NaN NaN NaN 李四 NaN NaN NaN 王五 NaN NaN NaN 赵六 NaN NaN -2.0

实操3:Series 与 DataFrame 的运算

in3

复制代码

# 创建学生成绩DataFrame data = { "语文": [80, 91, 86, 78], "数学": [70, 80, 91, 85], "英语": [85, 79, 88, 92] } df_score = pd.DataFrame(data, index=["张三", "李四", "赵六", "孙七"]) # 创建每科加分Series(与DataFrame列名对齐) add_score = pd.Series([5, 3, 4], index=["语文", "数学", "英语"]) print("原始成绩DataFrame:") print(df_score) print("\n每科加分Series:") print(add_score) # Series与DataFrame运算(每科成绩加对应分数) print("\nSeries与DataFrame运算(每科加对应分数):") print(df_score + add_score)

out3

复制代码

原始成绩DataFrame: 语文 数学 英语 张三 80 70 85 李四 91 80 79 赵六 86 91 88 孙七 78 85 92 每科加分Series: 语文 5 数学 3 英语 4 dtype: int64 Series与DataFrame运算(每科加对应分数): 语文 数学 英语 张三 85 73 89 李四 96 83 83 赵六 91 94 92 孙七 83 88 96

8.3 数学公式与聚合运算

实操1:数学公式运算(自定义表达式、apply方法)

in1

复制代码

# 导入所需库,创建DataFrame对象 import pandas as pd import numpy as np # 模拟学生成绩及权重DataFrame data = { "语文": [80, 91, 86, 78], "数学": [70, 80, 91, 85], "英语": [85, 79, 88, 92], "语文权重": [0.3, 0.3, 0.3, 0.3], "数学权重": [0.4, 0.4, 0.4, 0.4], "英语权重": [0.3, 0.3, 0.3, 0.3] } df_score = pd.DataFrame(data, index=["张三", "李四", "赵六", "孙七"]) print("原始成绩及权重数据:") print(df_score) # 1. 直接用表达式实现数学公式(加权平均分 = 语文*语文权重 + 数学*数学权重 + 英语*英语权重) df_score["加权平均分"] = df_score["语文"]*df_score["语文权重"] + df_score["数学"]*df_score["数学权重"] + df_score["英语"]*df_score["英语权重"] # 2. 用apply方法实现数学公式(计算每科成绩与平均分的差值) def score_diff(row): # 计算当前行三科成绩的平均分 avg = (row["语文"] + row["数学"] + row["英语"]) / 3 # 返回每科与平均分的差值 return pd.Series([row["语文"]-avg, row["数学"]-avg, row["英语"]-avg], index=["语文差值", "数学差值", "英语差值"]) # 应用函数,添加差值列 diff_df = df_score.apply(score_diff, axis=1) df_score = pd.concat([df_score, diff_df], axis=1) print("\n添加加权平均分和成绩差值后:") print(df_score.round(2)) # 保留2位小数

out1

复制代码

原始成绩及权重数据: 语文 数学 英语 语文权重 数学权重 英语权重 张三 80 70 85 0.3 0.4 0.3 李四 91 80 79 0.3 0.4 0.3 赵六 86 91 88 0.3 0.4 0.3 孙七 78 85 92 0.3 0.4 0.3 添加加权平均分和成绩差值后: 语文 数学 英语 语文权重 数学权重 英语权重 加权平均分 语文差值 数学差值 英语差值 张三 80 70 85 0.3 0.4 0.3 79.5 -1.67 -11.67 3.33 李四 91 80 79 0.3 0.4 0.3 83.0 8.00 -3.00 -5.00 赵六 86 91 88 0.3 0.4 0.3 88.7 0.33 6.33 3.33 孙七 78 85 92 0.3 0.4 0.3 86.3 -5.67 1.33 4.33

实操2:map() 与 lambda 表达式

in2

复制代码

import pandas as pd score = pd.Series([95, 82, 76, 59]) # 使用lambda划分等级 level = score.map(lambda x: "优秀" if x >= 90 else "良好" if x >= 80 else "及格" if x >= 60 else "不及格") print(level)

out2

复制代码

0 优秀 1 良好 2 及格 3 不及格 dtype: object

实操3:分组聚合运算(groupby + 聚合函数)

in3

复制代码

# 导入所需库,创建DataFrame对象 import pandas as pd import numpy as np # 模拟学生成绩及权重DataFrame data = { "语文": [80, 91, 86, 78], "数学": [70, 80, 91, 85], "英语": [85, 79, 88, 92], "班级": ["一班", "一班", "二班", "二班"] } df_score = pd.DataFrame(data, index=["张三", "李四", "赵六", "孙七"]) print("原始成绩及权重数据:") print(df_score) # 按班级分组,聚合每科成绩的均值、求和 grouped = df_score.groupby("班级")[["语文", "数学", "英语"]] print("\n1. 按班级分组,求每科均值:") print(grouped.mean().round(2)) print("\n2. 按班级分组,求每科求和:") print(grouped.sum()) print("\n3. 按班级分组,多函数聚合(均值、最大值、最小值):") print(grouped.agg(["mean", "max", "min"]).round(1))

out3

复制代码

原始成绩及权重数据: 语文 数学 英语 班级 张三 80 70 85 一班 李四 91 80 79 一班 赵六 86 91 88 二班 孙七 78 85 92 二班 1. 按班级分组,求每科均值: 语文 数学 英语 班级 一班 85.5 75.0 82.0 二班 82.0 88.0 90.0 2. 按班级分组,求每科求和: 语文 数学 英语 班级 一班 171 150 164 二班 164 176 180 3. 按班级分组,多函数聚合(均值、最大值、最小值): 语文 数学 英语 mean max min mean max min mean max min 班级 一班 85.5 91 80 75.0 80 70 82.0 85 79 二班 82.0 86 78 88.0 91 85 90.0 92 88

9. Pandas 分组与聚合

9.1 groupby() 分组操作

9.1.1 单列分组

实操1:按班级分组统计

in1

复制代码

# 导入所需库 import pandas as pd # 创建学生成绩数据 data = { "姓名": ["张三", "李四", "王五", "赵六", "孙七"], "班级": ["一班", "一班", "二班", "二班", "一班"], "语文": [88, 92, 85, 90, 87], "数学": [95, 89, 93, 87, 91] } df = pd.DataFrame(data) print("原始成绩数据:") print(df) # 按班级分组 grouped = df.groupby("班级") print("\n分组对象:") print(grouped)

out1

复制代码

原始成绩数据: 姓名 班级 语文 数学 0 张三 一班 88 95 1 李四 一班 92 89 2 王五 二班 85 93 3 赵六 二班 90 87 4 孙七 一班 87 91 分组对象: <pandas.core.groupby.generic.DataFrameGroupBy object at xxxx>

9.1.2 多列分组

实操2:按班级和性别分组

in2

复制代码

# 创建包含性别的数据 data = { "姓名": ["张三", "李四", "王五", "赵六", "孙七"], "班级": ["一班", "一班", "二班", "二班", "一班"], "性别": ["男", "女", "男", "男", "女"], "语文": [88, 92, 85, 90, 87] } df = pd.DataFrame(data) print("原始数据:") print(df) # 多列分组 grouped = df.groupby(["班级", "性别"]) print("\n按班级和性别分组后的语文平均分:") print(grouped["语文"].mean())

out2

复制代码

原始数据: 姓名 班级 性别 语文 0 张三 一班 男 88 1 李四 一班 女 92 2 王五 二班 男 85 3 赵六 二班 男 90 4 孙七 一班 女 87 按班级和性别分组后的语文平均分: 班级 性别 一班 女 89.5 男 88.0 二班 男 87.5 Name: 语文, dtype: float64

9.2 基础聚合函数

9.2.1 基础统计聚合

实操1:按班级统计各科平均分

in1

复制代码

import pandas as pd data = { "姓名": ["张三", "李四", "王五", "赵六", "孙七"], "班级": ["一班", "一班", "二班", "二班", "一班"], "语文": [88, 92, 85, 90, 87], "数学": [95, 89, 93, 87, 91] } df = pd.DataFrame(data) # 分组后统计均值 result = df.groupby("班级")[["语文", "数学"]].mean() print("按班级统计平均分:") print(result)

out1

复制代码

按班级统计平均分: 语文 数学 班级 一班 89.000000 91.666667 二班 87.500000 90.000000

9.2.2 count() 与 size() 的区别

实操2:count与size区别

in2

复制代码

import pandas as pd import numpy as np data = { "班级": ["一班", "一班", "二班", "二班"], "语文": [88, np.nan, 90, 85] } df = pd.DataFrame(data) print("原始数据:") print(df) grouped = df.groupby("班级") print("\ncount统计结果:") print(grouped.count()) print("\nsize统计结果:") print(grouped.size())

out2

复制代码

原始数据: 班级 语文 0 一班 88.0 1 一班 NaN 2 二班 90.0 3 二班 85.0 count统计结果: 语文 班级 一班 1 二班 2 size统计结果: 班级 一班 2 二班 2 dtype: int64

9.3 agg() 多函数聚合

9.3.1 单列多聚合

实操1:语文成绩多聚合统计

in1

复制代码

import pandas as pd data = { "班级": ["一班", "一班", "二班", "二班"], "语文": [88, 92, 85, 90] } df = pd.DataFrame(data) result = df.groupby("班级")["语文"].agg(["mean", "max", "min", "sum"]) print("语文成绩多聚合统计:") print(result)

out1

复制代码

语文成绩多聚合统计: mean max min sum 班级 一班 90.0 92 88 180 二班 87.5 90 85 175

9.3.2 多列不同聚合

实操2:不同列使用不同聚合函数

in2

复制代码

import pandas as pd data = { "班级": ["一班", "一班", "二班", "二班"], "语文": [88, 92, 85, 90], "数学": [95, 89, 93, 87] } df = pd.DataFrame(data) result = df.groupby("班级").agg({ "语文": ["mean", "max"], "数学": ["sum", "min"] }) print("不同列不同聚合统计:") print(result)

out2

复制代码

不同列不同聚合统计: 语文 数学 mean max sum min 班级 一班 90.0 92 184 89 二班 87.5 90 180 87

9.4 transform() 分组转换

9.4.1 分组均值填充

实操1:按班级计算组内平均分

in1

复制代码

import pandas as pd data = { "姓名": ["张三", "李四", "王五", "赵六"], "班级": ["一班", "一班", "二班", "二班"], "语文": [88, 92, 85, 90] } df = pd.DataFrame(data) # transform计算组内平均值 df["班级平均分"] = df.groupby("班级")["语文"].transform("mean") print("添加班级平均分后:") print(df)

out1

复制代码

添加班级平均分后: 姓名 班级 语文 班级平均分 0 张三 一班 88 90.0 1 李四 一班 92 90.0 2 王五 二班 85 87.5 3 赵六 二班 90 87.5

9.5 filter() 分组过滤

9.5.1 筛选平均分大于 90 的班级

实操1:分组过滤

in1

复制代码

import pandas as pd data = { "姓名": ["张三", "李四", "王五", "赵六"], "班级": ["一班", "一班", "二班", "二班"], "语文": [88, 92, 85, 90] } df = pd.DataFrame(data) # 筛选平均分大于88的班级 result = df.groupby("班级").filter( lambda x: x["语文"].mean() > 88 ) print("筛选后的数据:") print(result)

out1

复制代码

筛选后的数据: 姓名 班级 语文 0 张三 一班 88 1 李四 一班 92

9.6 分组后的排序与统计分析

9.6.1 分组结果排序

实操1:按平均分排序

in1

复制代码

import pandas as pd data = { "班级": ["一班", "一班", "二班", "二班"], "语文": [88, 92, 85, 90] } df = pd.DataFrame(data) # 分组求均值 result = df.groupby("班级")["语文"].mean() # 排序 result = result.sort_values(ascending=False) print("按平均分降序排序:") print(result)

out1

复制代码

按平均分降序排序: 班级 一班 90.0 二班 87.5 Name: 语文, dtype: float64

9.6.2 TopN 统计

实操2:统计成绩最高的前2名

in2

复制代码

import pandas as pd data = { "姓名": ["张三", "李四", "王五", "赵六", "孙七"], "语文": [88, 92, 85, 90, 87] } df = pd.DataFrame(data) # 获取前2名 top2 = df.nlargest(2, "语文") print("语文成绩前2名:") print(top2)

out2

复制代码

语文成绩前2名: 姓名 语文 1 李四 92 3 赵六 90

10. Pandas 时间数据处理

10.1 时间类型转换

实操:字符串转时间类型

in1

复制代码

import pandas as pd # 创建时间字符串Seriess = pd.Series([ "2025-01-01", "2025-02-15", "2025-03-20" ]) print("原始数据类型:") print(s.dtype)# 转换为datetime类型 s_datetime = pd.to_datetime(s) print("++\n++ 转换后的数据:") print(s_datetime) print("++\n++转换后的数据类型:") print(s_datetime.dtype)

out1

复制代码

原始数据类型: object 转换后的数据: 0 2025-01-01 1 2025-02-15 2 2025-03-20 dtype: datetime64[ns] 转换后的数据类型: datetime64[ns]

10.2 时间属性提取

实操:提取时间属性

in2

复制代码

import pandas as pd # 创建时间数据 df = pd.DataFrame({ "订单时间": pd.to_datetime([ "2025-01-01 10:30:25", "2025-02-15 14:20:10", "2025-03-20 08:15:50" ]) }) print("原始数据:") print(df) # 提取时间属性 df["年份"] = df["订单时间"].dt.year df["月份"] = df["订单时间"].dt.month df["日期"] = df["订单时间"].dt.day df["小时"] = df["订单时间"].dt.hour print("\n提取时间属性后:") print(df)

out2

复制代码

原始数据: 订单时间 0 2025-01-01 10:30:25 1 2025-02-15 14:20:10 2 2025-03-20 08:15:50 提取时间属性后: 订单时间 年份 月份 日期 小时 0 2025-01-01 10:30:25 2025 1 1 10 1 2025-02-15 14:20:10 2025 2 15 14 2 2025-03-20 08:15:50 2025 3 20 8

10.3 时间范围生成

实操:生成时间范围

in3

复制代码

import pandas as pd # 生成日期序列 date_range = pd.date_range( start="2025-01-01", periods=7, freq="D" ) print("生成的时间范围:") print(date_range)

out3

复制代码

生成的时间范围: DatetimeIndex(['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-04', '2025-01-05', '2025-01-06', '2025-01-07'], dtype='datetime64[ns]', freq='D')

10.4 时间索引操作

实操:时间索引筛选

in4

复制代码

import pandas as pd # 创建销售数据 df = pd.DataFrame({ "日期": pd.date_range("2025-01-01", periods=5), "销售额": [100, 120, 90, 150, 180] }) # 设置时间索引 df = df.set_index("日期") print("时间索引DataFrame:") print(df) # 按时间筛选 print("\n筛选2025-01-03之后的数据:") print(df.loc["2025-01-03":])

out4

复制代码

时间索引DataFrame: 销售额 日期 2025-01-01 100 2025-01-02 120 2025-01-03 90 2025-01-04 150 2025-01-05 180 筛选2025-01-03之后的数据: 销售额 日期 2025-01-03 90 2025-01-04 150 2025-01-05 180

时间索引支持按"年""月""日期范围"等方式快速筛选数据,例如:

复制代码

df.loc["2025-01"]

可直接筛选 2025 年 1 月 的数据。

10.5 时间差与时间运算

实操:时间差计算

in5

复制代码

import pandas as pd # 创建时间 start_time = pd.to_datetime("2025-01-01 08:00:00") # 创建时间差(核心知识点) delta = pd.Timedelta(days=2, hours=2, minutes=30) # 计算结束时间 end_time = start_time + delta print("开始时间:", start_time) print("时间差:", delta) print("结束时间:", end_time)

out5

复制代码

开始时间: 2025-01-01 08:00:00 结束时间: 2025-01-03 10:30:00 时间差: 2 days 02:30:00

实操:减法得到 Timedelta

in6

复制代码

import pandas as pd start_time = pd.to_datetime("2025-01-01 08:00:00") end_time = pd.to_datetime("2025-01-03 10:30:00") # 得到 Timedelta time_diff = end_time - start_time print(type(time_diff)) print(time_diff)

out6

复制代码

<class 'pandas._libs.tslibs.timedeltas.Timedelta'> 2 days 02:30:00

10.6 时间重采样(resample)

实操:按月统计销售额(降采样:日 → 月统计)

in7

复制代码

import pandas as pd import numpy as np # 构造数据 df = pd.DataFrame({ "date": pd.date_range("2025-01-01", periods=90), "销售额": np.random.randint(100, 500, size=90) }) print("原始数据:") print(df.head()) # 按月重采样(使用多个关键参数) monthly_sales = df.resample( rule="ME", # 按月 on="date", # 指定时间列(非索引) label="right", # 标签放在区间右端(月末) closed="right", # 区间右闭 origin="start_day" # 从每月月初对齐 ).sum() print("\n按月统计销售额:") print(monthly_sales)

out7

复制代码

原始数据: date 销售额 0 2025-01-01 326 1 2025-01-02 287 2 2025-01-03 338 3 2025-01-04 294 4 2025-01-05 224 按月统计销售额: 销售额 date 2025-01-31 9595 2025-02-28 8655 2025-03-31 9272

实操:升采样示例

in8

复制代码

import pandas as pd import numpy as np df = pd.DataFrame({ "date": pd.date_range("2025-01-01", periods=5, freq="D"), "销售额": [100, 200, 150, 300, 250] }) df = df.set_index("date") # 升采样:按小时扩展数据(会产生 NaN) hourly = df.resample("h").asfreq() print(hourly)

out6

复制代码

销售额 date 2025-01-01 00:00:00 100.0 2025-01-01 01:00:00 NaN 2025-01-01 02:00:00 NaN 2025-01-01 03:00:00 NaN 2025-01-01 04:00:00 NaN ... ... 2025-01-04 20:00:00 NaN 2025-01-04 21:00:00 NaN 2025-01-04 22:00:00 NaN 2025-01-04 23:00:00 NaN 2025-01-05 00:00:00 250.0 [97 rows x 1 columns]

实操:按天升采样到小时

in9

复制代码

import pandas as pd import numpy as np df = pd.DataFrame({ "date": pd.date_range("2025-01-01", periods=20, freq="D"), "price": np.random.randint(80, 120, size=20) }) # 设置时间索引 df = df.set_index("date") # 按周生成OHLC数据 weekly_ohlc = df.resample("W").ohlc() print(weekly_ohlc)

out9

复制代码

price open high low close date 2025-01-05 96 113 96 113 2025-01-12 91 104 83 104 2025-01-19 119 119 82 82 2025-01-26 87 87 87 87

10.7 时间窗口运算

实操:移动平均值计算

in10

复制代码

import pandas as pd # 创建时间序列 dates = pd.date_range("2025-01-01", periods=7) s = pd.Series( [100, 120, 90, 150, 180, 160, 170], index=dates ) print("原始数据:") print(s) # 计算3日移动平均(滚动窗口) rolling_mean = s.rolling( window=3, # 窗口大小 min_periods=1 # 至少1个数据就计算 ).mean() print("\n3日移动平均:") print(rolling_mean)

out10

复制代码

原始数据: 2025-01-01 100 2025-01-02 120 2025-01-03 90 2025-01-04 150 2025-01-05 180 2025-01-06 160 2025-01-07 170 Freq: D, dtype: int64 3日移动平均: 2025-01-01 100.000000 2025-01-02 110.000000 2025-01-03 103.333333 2025-01-04 120.000000 2025-01-05 140.000000 2025-01-06 163.333333 2025-01-07 170.000000 Freq: D, dtype: float64

11. Pandas 中的 Excel 操作

11.2 读取 CSV 文件

实操1:读取 CSV 文件(默认读取全部数据)

暂时无法在飞书文档外展示此内容

in1

复制代码

# 导入所需库 import pandas as pd import numpy as np # 读取CSV文件(默认读取全部数据,无需指定工作表) # 注意:需确保文件路径正确,若CSV与代码文件在同一文件夹,直接写文件名即可 df_read1 = pd.read_csv("学生成绩表.csv", #filepath_or_buffer encoding="utf-8" ) print("读取CSV文件的所有数据:") print(df_read1)

out1

复制代码

读取CSV文件的所有数据: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班

实操2:读取 CSV 中指定列和指定行

学生成绩表(冗余行).csv:

暂时无法在飞书文档外展示此内容

in2

复制代码

# 读取指定列(姓名、语文、数学),跳过前1行(跳过表头外的无效行) df_read2 = pd.read_csv( "学生成绩表(冗余行).csv", usecols=["姓名", "语文", "数学"], # 指定列名 skiprows=1, # 跳过前1行 encoding="utf-8" ) print("读取指定列、跳过前1行的数据:") print(df_read2)

out2

复制代码

读取指定列、跳过前1行的数据: 姓名 语文 数学 0 张三 80 70 1 李四 91 80 2 赵六 86 91 3 孙七 78 85 4 王五 85 76

实操3:读取无表头的 CSV 文件

暂时无法在飞书文档外展示此内容

in3

复制代码

# 读取无表头的CSV,手动指定列名 df_read3 = pd.read_csv( "无表头成绩表.csv", header=None, # 无表头 names=["姓名", "语文", "数学", "英语","班级"], # 手动指定列名 encoding="utf-8" ) print("读取无表头CSV,手动指定列名:") print(df_read3)

out3

复制代码

读取无表头CSV,手动指定列名: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班

11.3 写入 CSV 文件

实操1:将 DataFrame 写入 CSV(覆盖原有文件)

in1

复制代码

# 导入所需库,创建DataFrame import pandas as pd import numpy as np # 模拟处理后的学生成绩数据 data = { "姓名": ["张三", "李四", "赵六", "孙七", "王五"], "语文": [80, 91, 86, 78, 85], "数学": [70, 80, 91, 85, 76], "英语": [85, 79, 88, 92, 80], "班级": ["一班", "一班", "二班", "二班", "一班"] } df_write1 = pd.DataFrame(data) # 写入CSV,不写入索引,指定编码避免中文乱码 df_write1.to_csv( path_or_buf="处理后成绩表.csv", index=False, # 不写入索引 encoding="utf-8-sig" ) print("数据已写入CSV,文件名为:处理后成绩表.csv") # 读取验证写入结果 df_check1 = pd.read_csv("处理后成绩表.csv", encoding="utf-8") print("\n验证写入结果:") print(df_check1)

out1

复制代码

数据已写入CSV,文件名为:处理后成绩表.csv 验证写入结果: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班

实操2:向现有 CSV 中追加数据

in2

复制代码

# 模拟新增学生成绩数据 new_data = { "姓名": ["周六", "吴八"], "语文": [82, 79], "数学": [88, 90], "英语": [76, 83], "班级": ["二班", "一班"] } df_new = pd.DataFrame(new_data) # 向现有CSV追加数据(不覆盖原有内容) df_new.to_csv( "处理后成绩表.csv", mode="a", # 追加模式 index=False, header=False, # header=False避免重复写入表头 encoding="utf-8-sig" ) print("新增数据已追加到CSV") # 读取验证追加结果 df_check2 = pd.read_csv("处理后成绩表.csv", encoding="utf-8") print("\n追加后的数据:") print(df_check2)

out2

复制代码

新增数据已追加到CSV 追加后的数据: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班 5 周六 82 88 76 二班 6 吴八 79 90 83 一班

实操3:将多个 DataFrame 写入不同 CSV 文件

in3

复制代码

# 导入所需库,创建DataFrame import pandas as pd import numpy as np # 模拟处理后的学生成绩数据 data = { "姓名": ["张三", "李四", "赵六", "孙七", "王五"], "语文": [80, 91, 86, 78, 85], "数学": [70, 80, 91, 85, 76], "英语": [85, 79, 88, 92, 80], "班级": ["一班", "一班", "二班", "二班", "一班"] } df_write1 = pd.DataFrame(data) # 拆分数据为一班、二班两个DataFrame df_class1 = df_write1[df_write1["班级"] == "一班"].drop("班级", axis=1) df_class2 = df_write1[df_write1["班级"] == "二班"].drop("班级", axis=1) # 将两个DataFrame分别写入不同的CSV文件(对应原不同工作表) df_class1.to_csv("一班成绩表.csv", index=False, encoding="utf-8-sig") df_class2.to_csv("二班成绩表.csv", index=False, encoding="utf-8-sig") print("多个DataFrame已写入不同CSV文件") # 读取验证 df_class1_check = pd.read_csv("一班成绩表.csv", encoding="utf-8") df_class2_check = pd.read_csv("二班成绩表.csv", encoding="utf-8") print("\n一班成绩:") print(df_class1_check) print("\n二班成绩:") print(df_class2_check)

out3

复制代码

多个DataFrame已写入不同CSV文件 一班成绩: 姓名 语文 数学 英语 0 张三 80 70 85 1 李四 91 80 79 2 王五 85 76 80 二班成绩: 姓名 语文 数学 英语 0 赵六 86 91 88 1 孙七 78 85 92

11.4 CSV 高级操作

实操1:合并多个 CSV 文件(同结构)

in1

暂时无法在飞书文档外展示此内容

暂时无法在飞书文档外展示此内容

暂时无法在飞书文档外展示此内容

复制代码

# 导入所需库 import pandas as pd import os # 定义要合并的CSV文件路径(假设多个CSV在同一文件夹下,命名为"成绩1.csv""成绩2.csv") file_paths = ["成绩1.csv", "成绩2.csv", "成绩3.csv"] # 存储所有CSV数据的列表 all_data = [] # 循环读取每个CSV文件,添加到列表中 for file in file_paths: df = pd.read_csv(file, encoding="utf-8") all_data.append(df) # 合并所有DataFrame df_merge = pd.concat(all_data, ignore_index=True) # ignore_index=True重新生成索引 # 将合并后的数据写入新CSV df_merge.to_csv("合并后总成绩表.csv", index=False, encoding="utf-8-sig") print("多个CSV文件已合并完成") print("\n合并后的数据:") print(df_merge)

out1

复制代码

合并后的数据: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班 5 周六 82 88 76 二班 6 吴八 79 90 83 一班 7 郑九 87 83 89 一班 8 钱十 77 86 90 二班

实操2:拆分 CSV 文件(按指定列拆分)

in2

复制代码

# 读取要拆分的CSV文件 df_split = pd.read_csv("合并后总成绩表.csv", encoding="utf-8") # 按"班级"列拆分,每个班级生成一个CSV文件 classes = df_split["班级"].unique() # 获取所有班级(一班、二班) for cls in classes: # 筛选当前班级的数据 df_cls = df_split[df_split["班级"] == cls].drop("班级", axis=1) # 写入对应班级的CSV文件 df_cls.to_csv(f"{cls}成绩表.csv", index=False, encoding="utf-8-sig") print(f"{cls}成绩表已生成") # 验证拆分结果 df_check_class1 = pd.read_csv("一班成绩表.csv", encoding="utf-8") df_check_class2 = pd.read_csv("二班成绩表.csv", encoding="utf-8") print("\n一班拆分结果:") print(df_check_class1) print("\n二班拆分结果:") print(df_check_class2)

out2

复制代码

一班成绩表已生成 二班成绩表已生成 一班拆分结果: 姓名 语文 数学 英语 0 张三 80 70 85 1 李四 91 80 79 2 王五 85 76 80 3 吴八 79 90 83 4 郑九 87 83 89 二班拆分结果: 姓名 语文 数学 英语 0 赵六 86 91 88 1 孙七 78 85 92 2 周六 82 88 76 3 钱十 77 86 90

11.5 数据透视操作

实操1:基础数据透视(按班级、科目统计成绩均值)

in1

复制代码

# 导入所需库,读取数据(沿用之前的合并后总成绩表) import pandas as pd # 读取合并后的成绩数据 df = pd.read_csv("合并后总成绩表.csv", encoding="utf-8") print("原始数据:") print(df) # 基础数据透视:按班级(行)、科目(列)统计成绩均值 pivot1 = pd.pivot_table( data=df, index="班级", # 行:班级 values=["语文", "数学", "英语"], # 聚合字段:三科成绩 aggfunc="mean" # 聚合函数:均值 ) print("\n按班级、姓名透视(各科成绩均值):") print(pivot1.round(2))

out1

复制代码

原始数据: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班 5 周六 82 88 76 二班 6 吴八 79 90 83 一班 7 郑九 87 83 89 一班 8 钱十 77 86 90 二班 按班级、姓名透视(各科成绩均值): 数学 英语 语文 班级 一班 79.8 83.2 84.40 二班 87.5 86.5 80.75

实操2:多聚合函数透视(统计均值、总和、最大值)

in2

复制代码

# 沿用原始成绩数据 print("原始数据:") print(df) # 多聚合函数透视:按班级(行)统计各科成绩的均值、总和、最大值 pivot2 = pd.pivot_table( data=df, index="班级", values=["语文", "数学", "英语"], aggfunc=["mean", "sum", "max"], # 多个聚合函数 fill_value=0 # 用0填充缺失值 ) print("\n按班级透视(多聚合函数):") print(pivot2.round(2))

out2

复制代码

原始数据: 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班 5 周六 82 88 76 二班 6 吴八 79 90 83 一班 7 郑九 87 83 89 一班 8 钱十 77 86 90 二班 按班级透视(多聚合函数): mean sum max 数学 英语 语文 数学 英语 语文 数学 英语 语文 班级 一班 79.8 83.2 84.40 399 416 422 90 89 91 二班 87.5 86.5 80.75 350 346 323 91 92 86

实操3:多行列透视(按班级、姓名为行,科目为列)

in3

复制代码

print("原df") print(df) print("\n") # 使用melt将班级和姓名也作为索引 df_long = df.melt( id_vars=["班级", "姓名"], value_vars=["语文", "数学", "英语"], var_name="科目", value_name="成绩" ) print("使用melt将班级和姓名也作为索引") print(df_long) print("\n") # 多行列透视(塑型):行=班级+姓名,列=科目,聚合函数=成绩本身 pivot3 = pd.pivot_table( df_long, index=["班级", "姓名"], columns="科目", values="成绩", aggfunc="first" ) print("按班级、姓名为行,科目为列的透视表:") print(pivot3)

out3

复制代码

原df 姓名 语文 数学 英语 班级 0 张三 80 70 85 一班 1 李四 91 80 79 一班 2 赵六 86 91 88 二班 3 孙七 78 85 92 二班 4 王五 85 76 80 一班 5 周六 82 88 76 二班 6 吴八 79 90 83 一班 7 郑九 87 83 89 一班 8 钱十 77 86 90 二班 使用melt将班级和姓名也作为索引 班级 姓名 科目 成绩 0 一班 张三 语文 80 1 一班 李四 语文 91 2 二班 赵六 语文 86 3 二班 孙七 语文 78 4 一班 王五 语文 85 5 二班 周六 语文 82 6 一班 吴八 语文 79 7 一班 郑九 语文 87 8 二班 钱十 语文 77 9 一班 张三 数学 70 10 一班 李四 数学 80 11 二班 赵六 数学 91 12 二班 孙七 数学 85 13 一班 王五 数学 76 14 二班 周六 数学 88 15 一班 吴八 数学 90 16 一班 郑九 数学 83 17 二班 钱十 数学 86 18 一班 张三 英语 85 19 一班 李四 英语 79 20 二班 赵六 英语 88 21 二班 孙七 英语 92 22 一班 王五 英语 80 23 二班 周六 英语 76 24 一班 吴八 英语 83 25 一班 郑九 英语 89 26 二班 钱十 英语 90 按班级、姓名为行,科目为列的透视表: 科目 数学 英语 语文 班级 姓名 一班 吴八 90 83 79 张三 70 85 80 李四 80 79 91 王五 76 80 85 郑九 83 89 87 二班 周六 88 76 82 孙七 85 92 78 赵六 91 88 86 钱十 86 90 77

实操4:添加汇总行/列(margins=True)

in4

复制代码

# 透视表添加汇总行/列(总计) pivot4 = pd.pivot_table( data=df, index="班级", values=["语文", "数学", "英语"], aggfunc="sum", margins=True, # 显示汇总行/列 margins_name="总计" # 汇总行/列的名称 ) print("带汇总行/列的透视表:") print(pivot4)

out4

复制代码

带汇总行/列的透视表: 数学 英语 语文 班级 一班 399 416 422 二班 350 346 323 总计 749 762 745

这里补充一些 excel 操作的相关内容

  1. 例子

    1. 写入 excel

      复制代码

      import pandas as pd # 一班数据 df1 = pd.DataFrame({ "姓名": ["张三", "李四", "王五"], "学号": ["001", "002", "003"], "考试时间": ["2025-01-01", "2025-01-01", "2025-01-02"], "语文": [80, 91, 85], "数学": [70, 80, 76], "英语": [85, 79, 80], "备注": ["无", "缺考", "-"] }) # 二班数据 df2 = pd.DataFrame({ "姓名": ["赵六", "孙七"], "学号": ["004", "005"], "考试时间": ["2025-01-01", "2025-01-02"], "语文": [86, 78], "数学": [91, 85], "英语": [88, 92], "备注": ["无", "缺考"] }) # 写入 Excel(多 sheet) with pd.ExcelWriter("学生成绩表.xlsx") as writer: df1.to_excel(writer, sheet_name="一班", index=False) df2.to_excel(writer, sheet_name="二班", index=False)

    2. 读取 excel

      复制代码

      import pandas as pd df = pd.read_excel( "学生成绩表.xlsx", # 1. 读取指定 sheet sheet_name="一班", # 2. 指定索引列 index_col="学号", # 3. 指定数据类型(避免001变成1) dtype={"学号": str}, # 4. 指定缺失值 na_values=["无", "-", "缺考"], # 5. 自动解析日期 parse_dates=["考试时间"] ) print(df)

第三章:Matplotlib 可视化基础

1. 图像绘制入门

1.1 基础图像绘制

1.1.1 折线图:plt.plot() 核心参数详解

实操1:绘制基础折线图(y随x变化)

in1

复制代码

# 导入Matplotlib核心绘图模块pyplot,通常简写为plt import matplotlib.pyplot as plt import numpy as np # 1. 准备数据(x为0-9的整数,y为x的平方) x = np.arange(10) # 生成0,1,2,...,9的数组 y = x ** 2 # 计算x的平方,作为y轴数据 # 2. 绘制折线图,指定x、y轴数据,设置颜色为蓝色(color='b'),线型为实线(linestyle='-') plt.plot(x, y, color='b', linestyle='-') # 3. 显示图像(核心函数,必须调用才能看到绘制结果)

out1

实操2:基础折线图添加简单标注(标题、坐标轴标签)并且设定显示字体解决标签,标题中文乱码问题

in2

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 使用微软雅黑 # ====================================== # 1. 准备数据 x = np.arange(10) # x 为 0~9 y = x ** 3 # y 为 x 的立方 # 2. 绘制折线图 plt.plot(x, y, color='r', linestyle='--') # 3. 添加标题与坐标轴标签 plt.title("基础折线图(y = x^3)", fontsize=12) plt.xlabel("x轴(0-9)", fontsize=10) plt.ylabel("y轴(x的立方)", fontsize=10) # 5. 显示图像 plt.show()

out2

1.1.2 柱状图:plt.bar() 核心参数详解

实操1:绘制基础柱状图(单组分类数据)

in1

复制代码

import matplotlib.pyplot as plt import numpy as np # ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== # 1. 准备分类数据(x为类别标签位置,height为对应数值) x = np.arange(5) # 5个类别,位置为0,1,2,3,4 categories = ['类别A', '类别B', '类别C', '类别D', '类别E'] # 实际类别名称 height = [12, 25, 18, 30, 22] # 每个类别的数值 # 2. 绘制柱状图,设置宽度、颜色、边框颜色 plt.bar(x, height, width=0.6, color='skyblue', edgecolor='black') # 3. 设置x轴标签(替换默认的0,1,2,3,4为实际类别名称) plt.xticks(x, categories) # xticks用于设置x轴刻度标签 # 4. 添加标题和坐标轴标签 plt.title("基础柱状图(单组分类数据)", fontsize=12) plt.xlabel("类别", fontsize=10) plt.ylabel("数值", fontsize=10) # 5. 显示图像 plt.show()

out1

实操2:绘制带数值标注的柱状图(增强可读性)

in2

复制代码

# 1. 准备数据(产品销量对比) x = np.arange(4) products = ['产品1', '产品2', '产品3', '产品4'] sales = [89, 123, 98, 156] # 2. 绘制柱状图,设置不同柱子颜色 colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'] # 十六进制颜色列表 plt.bar(x, sales, width=0.5, color=colors, edgecolor='black') # 3. 设置x轴标签 plt.xticks(x, products) # 4. 为每个柱子添加数值标注(关键:在柱子顶部显示对应数值) for i in range(len(x)): # 第一个参数:标注的x位置, # 第二个参数:标注的y位置(柱子高度+2,避免与柱子重叠) # 第三个参数:标注的内容(销量数值) # ha='center'表示水平居中 # 字体大小为10磅 plt.text(x[i], sales[i]+2, str(sales[i]), ha='center', fontsize=10) # 5. 添加标题和坐标轴标签 plt.title("产品销量对比柱状图(带数值标注)", fontsize=12) plt.xlabel("产品名称", fontsize=10) plt.ylabel("销量(件)", fontsize=10) # 6. 显示网格线(仅显示y轴网格,更清晰) plt.grid(True, axis='y', alpha=0.3) # 7. 显示图像 plt.show()

out2

1.1.3 饼图:plt.pie() 核心参数详解

实操1:绘制基础饼图(带百分比和标签)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备占比数据(各部分数值,总和无需为100) data = [35, 25, 20, 15, 5] # 各部分数值,总和为100(也可不为100,函数自动计算占比) labels = ['成分A', '成分B', '成分C', '成分D', '成分E'] # 各部分标签 # 2. 绘制饼图,设置颜色、百分比显示、阴影 colors = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99', '#FF99CC'] plt.pie(x=data, labels=labels, autopct='%.1f%%', colors=colors, shadow=True) # 3. 设置饼图为正圆形(默认可能为椭圆形,保证比例均匀) plt.axis('equal') # 4. 添加标题 plt.title("基础饼图(各成分占比)", fontsize=12) # 5. 显示图像 plt.show()

out1

实操2:绘制带突出效果的饼图

in2

复制代码

# 1. 准备数据(学生成绩等级分布) grades = [45, 30, 15, 10] # 优秀、良好、及格、不及格的人数 labels = ['优秀', '良好', '及格', '不及格'] # 2. 设置突出效果(突出"优秀"部分,explode列表中对应位置设为0.1,其余为0) explode = [0.1, 0, 0, 0] # 3. 绘制饼图,设置百分比保留2位小数、起始角度90度 plt.pie( x=grades, labels=labels, autopct='%.2f%%', explode=explode, colors=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'], shadow=True, startangle=90 ) # 4. 设置饼图为正圆形:让 x 轴和 y 轴使用相同的单位长度,从而保证图形在几何上不被拉伸或压缩 plt.axis('equal') # 5. 添加标题 plt.title("学生成绩等级分布饼图(突出优秀部分)", fontsize=12) # 6. 显示图像 plt.show()

out2

1.2 Matlab 方式绘图

1.2.1 Matlab 方式绘制多线条折线图

实操1:Matlab 方式绘制多线条折线图

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据(x为0-5的等差数列,3条不同的y轴数据) x = np.linspace(0, 5, 100) # 0到5之间生成100个均匀分布的点 y1 = np.sin(x) # 正弦函数 y2 = np.cos(x) # 余弦函数 y3 = x # 线性函数 # 2. 依次绘制3条折线,分别设置颜色和标签(label用于图例) plt.plot(x, y1, color='b', label='y=sin(x)') plt.plot(x, y2, color='r', label='y=cos(x)') plt.plot(x, y3, color='g', label='y=x') # 3. 添加标题、坐标轴标签 plt.title("Matlab方式绘制多线条折线图", fontsize=12) plt.xlabel("x轴(0-5)") plt.ylabel("y轴") # 4. 显示图例(label参数的内容会在图例中显示,loc='upper left'设置图例位置) plt.legend(loc='upper left') # 5. 显示网格线(便于观察数据对应关系) plt.grid(True, alpha=0.3) # alpha设置网格线透明度,0-1之间 # 6. 显示图像 plt.show()

out1

1.2.2 Matlab 方式绘制子图

实操2:Matlab 方式绘制子图(同一窗口显示多个图像)

in2

复制代码

# 1. 准备数据(x为0-2π,y1为正弦,y2为余弦) x = np.linspace(0, 2*np.pi, 100) y1 = np.sin(x) y2 = np.cos(x) # 2. 创建子图(2行1列,当前绘制第1个子图,subplot(行数, 列数, 子图序号)) plt.subplot(2, 1, 1) # 绘制第1个子图(正弦函数) plt.plot(x, y1, color='b') plt.title("y=sin(x)") plt.grid(True, alpha=0.3) # 3. 切换到第2个子图(2行1列,第2个子图) plt.subplot(2, 1, 2) # 绘制第2个子图(余弦函数) plt.plot(x, y2, color='r') plt.title("y=cos(x)") plt.xlabel("x轴(0-2π)") plt.grid(True, alpha=0.3) # 4. 调整子图间距(避免标题和标签重叠) plt.tight_layout() # 5. 显示图像 plt.show()

out2

1.3 面向对象方式绘图

1.3.2 面向对象方式绘制基础折线图

实操1:面向对象方式绘制基础折线图

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据 x = np.arange(10) y = 2 * x + 3 # 线性函数y=2x+3 # 2. 手动创建Figure对象(画布),设置画布大小(figsize=(宽, 高),单位为英寸) fig = plt.figure(figsize=(8, 4)) # 3. 在Figure上创建Axes对象(绘图区域),默认创建1个Axes(整个画布) # 在一个画布(Figure)上,创建一个"1 行 1 列、位于第 1 个位置"的坐标系(Axes)对象 ax = fig.add_subplot(1, 1, 1) # 4. 通过Axes对象调用plot方法绘图,设置颜色和线型 ax.plot(x, y, color='purple', linestyle='-.') # 5. 通过Axes对象设置标题、坐标轴标签(与Matlab方式的plt.xxx对应ax.set_xxx) ax.set_title("面向对象方式绘制线性折线图", fontsize=12) ax.set_xlabel("x轴(0-9)") ax.set_ylabel("y轴(y=2x+3)") # 6. 设置网格线 ax.grid(True, alpha=0.3) # 7. 显示图像 plt.show()

out1

1.3.3 面向对象方式绘制复杂子图布局

实操2:面向对象方式绘制多子图(复杂布局)

in2

复制代码

# 1. 准备数据 x = np.linspace(0, 2*np.pi, 100) #生成一个从 0 到 2π、共 100 个点的等差数列 y1 = np.sin(x) y2 = np.cos(x) y3 = np.sin(x) + np.cos(x) y4 = np.sin(x) - np.cos(x) # 2. 创建Figure对象,设置画布大小 fig = plt.figure(figsize=(10, 8)) # 3. 创建2行2列的子图,分别获取4个Axes对象 ax1 = fig.add_subplot(2, 2, 1) # 第1行第1列 ax2 = fig.add_subplot(2, 2, 2) # 第1行第2列 ax3 = fig.add_subplot(2, 2, 3) # 第2行第1列 ax4 = fig.add_subplot(2, 2, 4) # 第2行第2列 # 4. 分别在4个Axes上绘图并定制 # 子图1:y=sin(x) ax1.plot(x, y1, color='b') ax1.set_title("y=sin(x)") ax1.grid(True, alpha=0.3) # 子图2:y=cos(x) ax2.plot(x, y2, color='r') ax2.set_title("y=cos(x)") ax2.grid(True, alpha=0.3) # 子图3:y=sin(x)+cos(x) ax3.plot(x, y3, color='g') ax3.set_title("y=sin(x)+cos(x)") ax3.set_xlabel("x轴") ax3.grid(True, alpha=0.3) # 子图4:y=sin(x)-cos(x) ax4.plot(x, y4, color='orange') ax4.set_title("y=sin(x)-cos(x)") ax4.set_xlabel("x轴") ax4.grid(True, alpha=0.3) # 5. 调整子图间距,避免重叠 # 自动调整子图的位置和间距,防止标题、坐标轴标签、刻度标签被画布边缘裁剪或相互重叠 fig.tight_layout() # 6. 显示图像 plt.show()

out2

1.3.4 多 Figure(多画布)演示

in3

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 准备通用数据(供多个fig使用) x = np.linspace(0, 2*np.pi, 100) y1 = np.sin(x) y2 = np.cos(x) y3 = np.tan(x) y4 = np.sin(x)*np.cos(x) # ------------------- 定义第一个fig(fig1):2行1列子图 ------------------- # 1. 创建第一个独立画布fig1,设置大小 fig1 = plt.figure(figsize=(8, 6)) # 2. 在fig1上创建2行1列的子图(2个ax) ax1_1 = fig1.add_subplot(2, 1, 1) # fig1的第1个子图 ax1_2 = fig1.add_subplot(2, 1, 2) # fig1的第2个子图 # 3. 在fig1的两个ax上绘图并定制 ax1_1.plot(x, y1, color='blue', label='y=sin(x)') ax1_1.set_title("fig1 - 子图1:y=sin(x)") ax1_1.legend() ax1_1.grid(True, alpha=0.3) ax1_2.plot(x, y2, color='red', label='y=cos(x)') ax1_2.set_title("fig1 - 子图2:y=cos(x)") ax1_2.set_xlabel("x轴(0-2π)") ax1_2.legend() ax1_2.grid(True, alpha=0.3) # 调整fig1的子图间距 fig1.tight_layout() # ------------------- 定义第二个fig(fig2):1行2列子图 ------------------- # 1. 创建第二个独立画布fig2,设置大小(与fig1不同) fig2 = plt.figure(figsize=(10, 4)) # 2. 在fig2上创建1行2列的子图(2个ax) ax2_1 = fig2.add_subplot(1, 2, 1) # fig2的第1个子图 ax2_2 = fig2.add_subplot(1, 2, 2) # fig2的第2个子图 # 3. 在fig2的两个ax上绘图并定制 ax2_1.plot(x, y3, color='green', label='y=tan(x)', linestyle='--') ax2_1.set_title("fig2 - 子图1:y=tan(x)") ax2_1.legend() ax2_1.grid(True, alpha=0.3) ax2_2.plot(x, y4, color='orange', label='y=sin(x)*cos(x)', linestyle='-.') ax2_2.set_title("fig2 - 子图2:y=sin(x)*cos(x)") ax2_2.set_xlabel("x轴(0-2π)") ax2_2.legend() ax2_2.grid(True, alpha=0.3) # 调整fig2的子图间距 fig2.tight_layout() # ------------------- 定义第三个fig(fig3):单个子图 ------------------- # 1. 创建第三个独立画布fig3,设置大小 fig3 = plt.figure(figsize=(6, 4)) # 2. 在fig3上创建1个ax(单个子图) ax3_1 = fig3.add_subplot(1, 1, 1) # 3. 在fig3的ax上绘图并定制 ax3_1.plot(x, y1+y2, color='purple', label='y=sin(x)+cos(x)') ax3_1.set_title("fig3 - 单个子图:y=sin(x)+cos(x)") ax3_1.set_xlabel("x轴(0-2π)") ax3_1.set_ylabel("y轴") ax3_1.legend() ax3_1.grid(True, alpha=0.3) # 4. 显示所有fig(plt.show()会一次性显示所有创建的fig,每个fig对应独立窗口) plt.show()

out3

1.4 推荐创建方式:plt.subplots()

1.4.1 subplots() 基础创建方式

实操:创建基础画布

in1

复制代码

import matplotlib.pyplot as plt fig, ax = plt.subplots() print(fig) print(ax)

out1

1.4.2 单个子图绘制

实操:单个子图绘制折线图

in2

复制代码

import matplotlib.pyplot as plt x = [1,2,3,4] y = [2,4,6,8] fig, ax = plt.subplots() ax.plot(x, y) ax.set_title("折线图") ax.set_xlabel("X轴") ax.set_ylabel("Y轴") plt.show()

1.4.3 多子图绘制

实操:绘制多个子图

in3

复制代码

import matplotlib.pyplot as plt fig, axes = plt.subplots(2,2) axes[0,0].plot([1,2,3], [1,4,9]) axes[0,1].bar([1,2,3], [3,5,7]) axes[1,0].scatter([1,2,3], [2,4,6]) axes[1,1].pie([30,20,50]) plt.show()

1.4.4 axes 数组的访问方式

实操:遍历所有子图

in4

复制代码

import matplotlib.pyplot as plt fig, axes = plt.subplots(2,2) for ax in axes.flatten(): ax.plot([1,2,3], [1,4,9]) plt.show()

1.4.5 tight_layout 与 constrained_layout

实操 in5

复制代码

import matplotlib.pyplot as plt fig, axes = plt.subplots(2,2) for ax in axes.flatten(): ax.plot([1,2,3], [1,4,9]) plt.tight_layout() plt.show()

实操 in6

复制代码

import matplotlib.pyplot as plt fig, axes = plt.subplots( 2, 2, constrained_layout=True ) for ax in axes.flatten(): ax.plot([1,2,3], [1,4,9]) plt.show()

1.5 图像风格样式

实操:ggplot 风格

in7

复制代码

import matplotlib.pyplot as plt plt.style.use("ggplot") x = [1,2,3,4] y = [2,4,6,8] plt.plot(x, y) plt.show()

实操:深色主题

in8

复制代码

import matplotlib.pyplot as plt plt.style.use("dark_background") plt.plot([1,2,3], [1,4,9]) plt.show()

1.5.2 查看所有内置风格

实操:

in9

复制代码

import matplotlib.pyplot as plt print(plt.style.available)

1.5.3 rcParams 全局配置

实操:修改全局配置

in10

复制代码

import matplotlib.pyplot as plt plt.rcParams["figure.figsize"] = (8,4) plt.rcParams["lines.linewidth"] = 3 plt.plot([1,2,3], [1,4,9]) plt.show()

实操:中文字体配置

in11

复制代码

import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False plt.plot([1,2,3], [1,4,9]) plt.title("中文标题") plt.show()

1.5.4 默认风格恢复

实操:

in12

复制代码

import matplotlib.pyplot as plt plt.style.use("ggplot") plt.style.use("default") plt.plot([1,2,3], [1,4,9]) plt.show()

1.6 文本、注释与箭头

1.6.1 plt.text() 文本绘制

实操:添加文本

in13

复制代码

import matplotlib.pyplot as plt import numpy as np # 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False x = np.arange(10) y = x ** 2 plt.plot(x, y) # 添加文本 plt.text( 5, 25, "关键点", fontsize=12, color="red", rotation=0, ha="center", va="bottom" ) plt.title("plt.text()示例") plt.xlabel("横坐标") plt.ylabel("纵坐标") plt.show()

1.6.2 plt.annotate() 注释

实操:添加注释

in14

复制代码

import matplotlib.pyplot as plt x = [1,2,3] y = [1,4,9] plt.plot(x, y) plt.annotate( "最大值", xy=(3,9) ) plt.show()

1.6.3 箭头样式 arrowprops

实操:带箭头注释

in15

复制代码

import matplotlib.pyplot as plt x = [1,2,3] y = [1,4,9] plt.plot(x, y) plt.annotate( "峰值", xy=(3,9), xytext=(2,7), arrowprops=dict( arrowstyle='->' ) ) plt.show()

1.6.4 数据峰值标注案例

实操:峰值标注

in16

复制代码

import matplotlib.pyplot as plt x = [1,2,3,4,5] y = [3,5,9,6,4] plt.plot(x, y) max_y = max(y) max_x = x[y.index(max_y)] plt.annotate( "最大值", xy=(max_x, max_y), xytext=(max_x, max_y+1), arrowprops=dict( arrowstyle='->' ) ) plt.show()

1.6.5 折线图关键点标注案例

实操:关键点说明

in17

复制代码

import matplotlib.pyplot as plt x = [1,2,3,4] y = [2,8,5,10] plt.plot(x, y) plt.annotate( "数据增长", xy=(2,8), xytext=(1.5,9), arrowprops=dict( arrowstyle='->' ) ) plt.show()

1.7 图像的保存

实操1:Matlab方式保存图像

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据并绘制图像 x = np.arange(10) y = x ** 2 plt.plot(x, y, color='b', linestyle='-') plt.title("Matlab方式保存图像示例") plt.xlabel("x轴") plt.ylabel("y轴(y=x²)") plt.grid(True, alpha=0.3) # 2. 保存图像(关键:savefig必须在show()之前) # fname:保存路径(当前目录)+ 文件名+格式,dpi=300,裁剪空白 plt.savefig("matlab_save_example.png", dpi=300, bbox_inches='tight', facecolor='white') # 3. 显示图像 plt.show()

out1

可以看到已经保存成功了

点击查看

实操2:面向对象方式保存图像

in2

复制代码

# 1. 准备数据,创建Figure和Axes对象并绘图 x = np.linspace(0, 2*np.pi, 100) y = np.sin(x) fig = plt.figure(figsize=(8, 4)) ax = fig.add_subplot(1, 1, 1) ax.plot(x, y, color='r') ax.set_title("面向对象方式保存图像示例") ax.set_xlabel("x轴(0-2π)") ax.set_ylabel("y=sin(x)") ax.grid(True, alpha=0.3) # 2. 面向对象方式保存图像(通过fig对象调用savefig) fig.savefig("object_save_example.pdf", dpi=300, bbox_inches='tight', facecolor='lightgray') # 3. 显示图像 plt.show()

out2

可以查看目录发现已经保存成功

点击查看

2. 各类图表详细介绍

2.1 二维图

实操:绘制二维散点图(展示两个变量的关联关系)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据(模拟身高与体重的关联数据) np.random.seed(123) # 设置随机种子,保证结果可复现 height = np.random.normal(170, 5, 100) # 100个身高数据(均值170,标准差5) weight = np.random.normal(65, 8, 100) # 100个体重数据(均值65,标准差8) # 2. 绘制二维散点图,设置点的大小、颜色、样式和透明度 plt.scatter( x=height, y=weight, s=50, c='skyblue', marker='o', alpha=0.7, edgecolor='black' ) # 3. 添加标题和坐标轴标签 plt.title("二维散点图(身高与体重关联关系)", fontsize=12) plt.xlabel("身高(cm)", fontsize=10) plt.ylabel("体重(kg)", fontsize=10) # 4. 显示网格线,便于观察数据分布 plt.grid(True, alpha=0.3) # 5. 显示图像 plt.show()

out1

2.2 网格图(选学)

实操:绘制二维网格热力图(展示函数值分布)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 生成二维网格坐标(x、y轴范围均为-5到5,生成100个网格点) # 起点:-5 # 终点:5 #点数:100 个 x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) # 广播生成网格坐标,X、Y均为100x100的二维数组 # meshgrid 把x和y变成了两个尺寸相同的矩阵赋值给了X和Y # X,Y描述的是矩阵中第 i,j 个点的X轴坐标和Y轴坐标 # 2. 计算每个网格点的函数值(以二维高斯函数为例,模拟数据分布) Z = np.exp(-(X**2 + Y**2) / 10) # 高斯函数,中心数值大,边缘数值小 # 3. 绘制网格热力图 img = plt.imshow(Z, cmap='coolwarm', extent=[-5, 5, -5, 5], aspect='auto') # 4. 添加颜色条(关键:显示颜色与数值的对应关系) plt.colorbar(img, label='函数值 Z') # 5. 添加标题和坐标轴标签 plt.title("二维网格热力图(高斯函数值分布)", fontsize=12) plt.xlabel("x轴", fontsize=10) plt.ylabel("y轴", fontsize=10) # 6. 显示图像 plt.show()

out1

2.3 统计图

2.3.1 直方图(plt.hist())

实操1:绘制直方图(展示数据分布)

in1

复制代码

# 1. 准备数据(模拟学生成绩,服从正态分布,均值80,标准差5) scores = np.random.normal(80, 5, 200) # 200个成绩数据 # 2. 绘制直方图,设置区间数量、颜色、边框 plt.hist( x=scores, bins=15, color='lightgreen', edgecolor='black', alpha=0.7, density=False ) # 3. 添加标题和坐标轴标签 plt.title("学生成绩直方图(正态分布)", fontsize=12) plt.xlabel("成绩", fontsize=10) plt.ylabel("学生人数(频数)", fontsize=10) # 4. 显示网格线 plt.grid(True, axis='y', alpha=0.3) # 5. 显示图像 plt.show()

out1

2.3.2 箱线图(plt.boxplot())

实操2:绘制箱线图(多组数据离散程度对比)

in2

复制代码

# 1. 准备数据(模拟3个班级的学生成绩,多组数据) class1 = np.random.normal(82, 4, 50) # 班级1成绩,均值82,标准差4 class2 = np.random.normal(78, 6, 50) # 班级2成绩,均值78,标准差6 class3 = np.random.normal(85, 3, 50) # 班级3成绩,均值85,标准差3 data = [class1, class2, class3] # 多组数据,放入列表 # 2. 绘制箱线图,设置标签、填充颜色、显示异常值 box = plt.boxplot( x=data, tick_labels=['班级1', '班级2', '班级3'], patch_artist=True, showfliers=True ) # 3. 为箱体设置不同颜色 colors = ['lightblue', 'lightgreen', 'lightcoral'] for patch, color in zip(box['boxes'], colors): patch.set_facecolor(color) # 4. 添加标题和坐标轴标签 plt.title("3个班级学生成绩箱线图(离散程度对比)", fontsize=12) plt.xlabel("班级", fontsize=10) plt.ylabel("成绩", fontsize=10) # 5. 显示网格线 plt.grid(True, axis='y', alpha=0.3) # 6. 显示图像 plt.show()

out2

2.4 轮廓图(选学)

实操:绘制填充轮廓图(展示三维函数的二维投影)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 生成二维网格坐标(x、y轴范围均为-6到6,100个网格点) x = np.linspace(-6, 6, 100) y = np.linspace(-6, 6, 100) X, Y = np.meshgrid(x, y) # 2. 计算z轴数值(以双变量函数为例,模拟地形分布) Z = np.sin(np.sqrt(X**2 + Y**2)) / (np.sqrt(X**2 + Y**2) + 1e-6) # 避免分母为0 # 3. 绘制填充轮廓图,设置轮廓数量、颜色映射 contour = plt.contourf(X, Y, Z, levels=20, cmap='viridis') # 4. 添加颜色条,标注数值对应关系 plt.colorbar(contour, label='函数值 Z') # 5. 绘制轮廓线(叠加在填充图上,增强轮廓感,颜色为黑色,线型为实线) plt.contour(X, Y, Z, levels=20, colors='black', linewidths=0.5) # 6. 添加标题和坐标轴标签 plt.title("填充轮廓图(双变量函数二维投影)", fontsize=12) plt.xlabel("x轴", fontsize=10) plt.ylabel("y轴", fontsize=10) # 7. 显示图像 plt.show()

out1

2.5 三维图(选学)

实操1:绘制三维散点图(展示三个变量的关联)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D # 导入三维模块 # 1. 准备三维数据(模拟x、y、z三个变量的关联数据) np.random.seed(123) x = np.random.normal(0, 1, 100) y = np.random.normal(0, 1, 100) z = x**2 + y**2 # z与x、y的关联关系(抛物面分布) # 2. 创建画布和三维坐标轴 fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') # 3. 绘制三维散点图,设置点的大小、颜色、透明度 ax.scatter( x, y, z, s=50, c='orange', alpha=0.7, marker='o', edgecolor='black' ) # 4. 设置三维坐标轴标签和标题 ax.set_title("三维散点图(z = x² + y²)", fontsize=12) ax.set_xlabel("x轴", fontsize=10) ax.set_ylabel("y轴", fontsize=10) ax.set_zlabel("z轴", fontsize=10) # 5. 显示图像 plt.show()

out1

实操2:绘制三维曲面图(展示三维函数的立体形态)

in2

复制代码

# 1. 生成三维网格坐标和z轴数值 x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) Z = np.sin(np.sqrt(X**2 + Y**2)) # 三维正弦函数,模拟立体曲面 # 2. 创建画布和三维坐标轴 fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') # 3. 绘制三维曲面图,设置颜色映射、透明度 surface = ax.plot_surface( X, Y, Z, cmap='viridis', alpha=0.8, edgecolor='none' ) # 4. 添加颜色条,标注z轴数值对应关系 fig.colorbar(surface, ax=ax, label='z轴数值') # 5. 设置标题和坐标轴标签 ax.set_title("三维曲面图(z = sin(√(x²+y²)))", fontsize=12) ax.set_xlabel("x轴", fontsize=10) ax.set_ylabel("y轴", fontsize=10) ax.set_zlabel("z轴", fontsize=10) # 6. 显示图像 plt.show()

out2

3. 图窗

3.1 坐标轴上下限

实操1:Matlab 方式设置坐标轴上下限

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据(模拟数据,x为0-20,y为sin(x)) x = np.linspace(0, 20, 100) y = np.sin(x) # 2. 绘制折线图 plt.plot(x, y, color='blue', linestyle='--') # 3. 设置坐标轴上下限(聚焦x轴5-15,y轴-1.2到1.2) plt.xlim(5, 15) # x轴范围:5~15 plt.ylim(-1.2, 1.2) # y轴范围:-1.2~1.2(贴合sin(x)的取值范围) # 4. 添加标题和坐标轴标签 plt.title("Matlab方式设置坐标轴上下限", fontsize=12) plt.xlabel("x轴(5-15)") plt.ylabel("y轴(sin(x))") plt.grid(True, alpha=0.3) # 5. 显示图像 plt.show()

实操2:面向对象方式设置坐标轴上下限(单侧设置)

in2

复制代码

# 1. 准备数据(模拟身高数据,均值170,标准差5) np.random.seed(123) height = np.random.normal(170, 5, 100) weight = np.random.normal(65, 8, 100) # 2. 手动创建fig和ax fig = plt.figure(figsize=(8, 4)) ax = fig.add_subplot(1, 1, 1) # 3. 绘制散点图 ax.scatter(height, weight, color='skyblue', alpha=0.7, edgecolor='black') # 4. 单侧设置坐标轴上下限(仅设置y轴最小值为50,其他保持默认) ax.set_ylim(bottom=50) # y轴下限设为50,上限自动适配数据 ax.set_xlim(left=160, right=180) # 双侧设置x轴范围 # 5. 定制标题和标签 ax.set_title("面向对象方式设置坐标轴上下限(单侧+双侧)", fontsize=12) ax.set_xlabel("身高(cm)") ax.set_ylabel("体重(kg)") ax.grid(True, alpha=0.3) # 6. 显示图像 plt.show()

3.2 标题与轴名称

实操1:定制标题与轴名称样式(Matlab方式)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据 x = np.arange(10) y = x ** 2 + 2*x + 1 # 2. 绘制折线图 plt.plot(x, y, color='purple', linewidth=2) # 3. 定制标题(加粗、红色、字体14) plt.title("二次函数图像(y = x² + 2x + 1)", fontsize=14, fontweight='bold', color='red', pad=15) # 4. 定制轴名称(字体10、加粗、蓝色) plt.xlabel("x轴(0-9)", fontsize=10, fontweight='bold', color='#45B7D1') plt.ylabel("y轴(二次函数值)", fontsize=10, fontweight='bold', color='#45B7D1') # 5. 显示网格和图像 plt.grid(True, alpha=0.3) plt.show()

实操2:面向对象方式设置多子图标题与轴名称

in2

复制代码

# 1. 准备数据 x = np.linspace(0, 2*np.pi, 100) y1 = np.sin(x) y2 = np.cos(x) # 2. 创建fig和2行1列子图 fig = plt.figure(figsize=(8, 6)) ax1 = fig.add_subplot(2, 1, 1) ax2 = fig.add_subplot(2, 1, 2) # 3. 绘制子图并定制标题、轴名称 # 子图1:sin(x) ax1.plot(x, y1, color='blue') ax1.set_title("y = sin(x)", fontsize=12, fontweight='bold', pad=10) ax1.set_ylabel("y轴", fontsize=10, color='blue') ax1.grid(True, alpha=0.3) # 子图2:cos(x) ax2.plot(x, y2, color='red') ax2.set_title("y = cos(x)", fontsize=12, fontweight='bold', pad=10) ax2.set_xlabel("x轴(0-2π)", fontsize=10, color='red') ax2.set_ylabel("y轴", fontsize=10, color='red') ax2.grid(True, alpha=0.3) # 4. 调整子图间距,避免标题重叠 plt.tight_layout() # 5. 显示图像 plt.show()

3.3 图例

实操1:基础图例设置(多线条折线图)

in1

复制代码

# ========= 解决中文乱码================= plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 设置为微软雅黑 plt.rcParams['axes.unicode_minus'] = False # ====================================== import matplotlib.pyplot as plt import numpy as np # 1. 准备数据 x = np.linspace(0, 5, 100) y1 = np.sin(x) y2 = np.cos(x) y3 = x # 2. 绘制多线条,设置label(图例的核心前提) plt.plot(x, y1, color='blue', label='y=sin(x)') plt.plot(x, y2, color='red', label='y=cos(x)') plt.plot(x, y3, color='green', label='y=x') # 3. 设置图例(位置右上、字体10、显示边框、添加图例标题) plt.legend( loc='upper right', fontsize=10, frameon=True, labelspacing=0.8, title='函数类型', title_fontsize=11 ) # 4. 定制标题和轴名称 plt.title("多线条折线图(图例演示)", fontsize=12) plt.xlabel("x轴(0-5)") plt.ylabel("y轴") plt.grid(True, alpha=0.3) # 5. 显示图像 plt.show()

实操2:面向对象方式设置图例(多组散点图)

in2

复制代码

# 1. 准备多组数据(模拟两个班级的身高体重数据) np.random.seed(123) # 班级A height_a = np.random.normal(170, 5, 50) weight_a = np.random.normal(65, 8, 50) # 班级B height_b = np.random.normal(165, 6, 50) weight_b = np.random.normal(60, 7, 50) # 2. 创建fig和ax fig = plt.figure(figsize=(8, 5)) ax = fig.add_subplot(1, 1, 1) # 3. 绘制多组散点,设置label ax.scatter(height_a, weight_a, color='skyblue', label='班级A', alpha=0.7, edgecolor='black') ax.scatter(height_b, weight_b, color='lightcoral', label='班级B', alpha=0.7, edgecolor='black') # 4. 设置图例(位置左下、不显示边框、字体10) ax.legend(loc='lower left', fontsize=10, frameon=False) # 5. 定制标题和轴名称 ax.set_title("两个班级身高体重散点图(图例区分)", fontsize=12) ax.set_xlabel("身高(cm)") ax.set_ylabel("体重(kg)") ax.grid(True, alpha=0.3) # 6. 显示图像 plt.show()

3.4 双坐标轴

3.4.1 twinx() 双y轴
复制代码

import matplotlib.pyplot as plt x = ["周一", "周二", "周三", "周四", "周五"] sales = [120, 150, 180, 170, 200] growth = [5, 8, 12, 10, 15] fig, ax1 = plt.subplots() # 左侧Y轴 ax1.plot(x, sales) # 创建右侧Y轴 ax2 = ax1.twinx() ax2.plot(x, growth) plt.show()

3.4.2 柱状图 + 折线图组合案例
复制代码

import matplotlib.pyplot as plt months = ["1月", "2月", "3月", "4月", "5月"] sales = [300, 420, 500, 480, 620] rate = [5, 8, 12, 10, 15] fig, ax1 = plt.subplots() # 柱状图 ax1.bar(months, sales) # 第二坐标轴 ax2 = ax1.twinx() # 折线图 ax2.plot(months, rate, marker="o") plt.show()

3.4.3 双轴颜色区分技巧
复制代码

import matplotlib.pyplot as plt x = ["周一", "周二", "周三", "周四"] sales = [100, 150, 180, 200] rate = [3, 5, 8, 10] fig, ax1 = plt.subplots() # 左轴 ax1.bar(x, sales, color="skyblue") ax1.set_ylabel("销售额", color="blue") ax1.tick_params(axis="y", labelcolor="blue") # 右轴 ax2 = ax1.twinx() ax2.plot(x, rate, color="red", marker="o") ax2.set_ylabel("增长率", color="red") ax2.tick_params(axis="y", labelcolor="red") plt.show()

3.5 坐标轴脊柱(选学)

3.5.1 spines 对象
复制代码

import matplotlib.pyplot as plt fig, ax = plt.subplots() print(ax.spines)

3.5.2 隐藏边框
复制代码

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], [2, 4, 6]) # 隐藏边框 ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) plt.show()

3.5.3 坐标轴移动
复制代码

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([-3, -2, -1, 0, 1, 2, 3], [9, 4, 1, 0, 1, 4, 9]) # 移动坐标轴 ax.spines['left'].set_position('zero') ax.spines['bottom'].set_position('zero') # 隐藏其他边框 ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) plt.show()

3.5.4 极简风格绘图
复制代码

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3, 4], [2, 5, 3, 6]) # 极简风格 ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) plt.show()

相关推荐
阿洛学长1 小时前
计算机二级 Python 基本操作题(15 分)真题笔记(0101 ~ 1903 全套)
python·pycharm
weixin199701080161 小时前
[特殊字符]️《二手ERP对接电商平台的总体方案:统一数据模型 + 事件驱动 + 灰度上线6原则》(附Python源码)
大数据·python
滚雪球~2 小时前
量化交易 防止Windows电脑自动更新并重启
python·量化
L@ncor3 小时前
第二章可能出现的问题
人工智能·python
y = xⁿ3 小时前
大模型基础概念
python
ctlover3 小时前
排序与查找算法详解
开发语言·python
用户8356290780513 小时前
如何使用 Python 给 Word 文档添加水印
后端·python
泡干脆面就番茄4 小时前
深度学习:PyTorch框架初识——MNIST手写数字识别
python·深度学习
shirsl4 小时前
算法 Day 5 树 / 二叉树 + DFS
数据结构·python·算法