构建AI智能体:AI数据科学NumPy — 不可不知、由点及面抽丝剥茧+趣味范例

numpy(numerical python)是 python 科学计算生态系统的核心库,提供了高性能的多维数组对象和用于处理这些数组的工具。如:矩阵数据类型、矢量处理,以及精密的运算库。它是几乎所有数据科学、机器学习和科学计算库的基础。广泛应用于数据分析、机器学习等领域,是 pandas 、 scikit-learn 等库的基础。

下图是NumPy通过蒙特卡洛方法估算圆周率π,并提供详细的代码实现和可视化,感兴趣可在后文根据详细注解一探究竟;

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

构建AI智能体:AI数据科学NumPy — 不可不知、由点及面抽丝剥茧+趣味范例

一、NumPy的优势

1. 与Python 列表的比较

与Python列表的比较,直观体现性能优势:

import numpy as npimport time# Python 列表的性能问题python_list = list(range(1000000))start_time = time.time()result = [x * 2 for x in python_list]end_time = time.time()print(f"Python列表计算时间: {end_time - start_time:.6f}秒")# NumPy 数组的性能优势numpy_array = np.arange(1000000)start_time = time.time()result = numpy_array * 2end_time = time.time()print(f"NumPy数组计算时间: {end_time - start_time:.6f}秒")

结果展示:

Python列表计算时间: 0.045234秒NumPy数组计算时间: 0.001567秒

2、主要优势

由于底层用 C 语言实现,运算速度极快 数组元素在内存中连续存储,效率极高 向量化操作,避免显式循环,一次操作整个数组 广播机制,处理不同形状的数组之间的逐元素运算 丰富的数学函数、线性代数、随机数生成等

二、由浅入深、循序渐进

1. 核心对象:ndarray

1.1 创建数组

import numpy as np# 从列表创建arr1 = np.array([1, 2, 3, 4, 5])print("从列表创建:", arr1)# 创建特殊数组zeros = np.zeros((3, 4))        # 全0数组ones = np.ones((2, 3))          # 全1数组empty = np.empty((2, 2))        # 未初始化数组full = np.full((2, 2), 7)       # 填充指定值identity = np.eye(3)            # 单位矩阵print("全0数组:", zeros)print("单位矩阵:", identity)# 创建序列数组range_arr = np.arange(0, 10, 2)  # 类似range,但返回数组linear_arr = np.linspace(0, 1, 5)  # 等间隔数列random_arr = np.random.rand(3, 3)  # 随机数组print("arange创建:", range_arr)print("linspace创建:", linear_arr)print("随机数组:", random_arr)

输出结果:​​​​​​

从列表创建: [1 2 3 4 5]全0数组: [[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]单位矩阵: [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]]arange创建: [0 2 4 6 8]linspace创建: [0.   0.25 0.5  0.75 1.  ]随机数组: [[0.39898071 0.38841929 0.25706792] [0.4805703  0.79778008 0.96680553] [0.75744912 0.35779339 0.96884091]]

1.2 数组属性

import numpy as np# 创建一个示例数组arr = np.array([[1, 2, 3], [4, 5, 6]])print("数组:", arr)print("形状:", arr.shape)        # 数组维度print("大小:", arr.size)         # 元素总数print("维度:", arr.ndim)         # 轴的数量print("数据类型:", arr.dtype)    # 元素类型print("每个元素字节数:", arr.itemsize)print("总字节数:", arr.nbytes)

输出结果:

组: [[1 2 3] [4 5 6]]形状: (2, 3)大小: 6维度: 2数据类型: int32每个元素字节数: 4总字节数: 24

2. 数组操作

2.1 索引和切片

import numpy as np# 创建示例数组arr = np.arange(1, 13).reshape(3, 4)print("原始数组:", arr)# 基本索引print("第一个元素:", arr[0, 0])print("第一行:", arr[0])print("第一列:", arr[:, 0])# 切片操作print("前两行:", arr[:2])print("后两列:", arr[:, -2:])print("子数组:", arr[1:3, 1:3])# 布尔索引bool_mask = arr > 5print("布尔掩码:", bool_mask)print("大于5的元素:", arr[bool_mask])# 花式索引print("选择特定行:", arr[[0, 2]])print("选择特定列:", arr[:, [1, 3]])

输出结果:

始数组: [[ 1  2  3  4] [ 5  6  7  8] [ 9 10 11 12]]第一个元素: 1第一行: [1 2 3 4]第一列: [1 5 9]前两行: [[1 2 3 4] [5 6 7 8]]后两列: [[ 3  4] [ 7  8] [11 12]]子数组: [[ 6  7] [10 11]]布尔掩码: [[False False False False] [False  True  True  True] [ True  True  True  True]]大于5的元素: [ 6  7  8  9 10 11 12]选择特定行: [[ 1  2  3  4] [ 9 10 11 12]]选择特定列: [[ 2  4] [ 6  8] [10 12]]

2.2 形状操作

import numpy as nparr = np.arange(12)print("一维数组:", arr)# 改变形状reshaped = arr.reshape(3, 4)print("重塑为3x4:", reshaped)# 展平数组flattened = reshaped.flatten()print("展平:", flattened)# 转置transposed = reshaped.Tprint("转置:", transposed)# 增加/减少维度expanded = np.expand_dims(arr, axis=0)print("增加维度:", expanded.shape)squeezed = np.squeeze(expanded)print("压缩维度:", squeezed.shape)

输出结果:

维数组: [ 0  1  2  3  4  5  6  7  8  9 10 11]重塑为3x4: [[ 0  1  2  3] [ 4  5  6  7] [ 8  9 10 11]]展平: [ 0  1  2  3  4  5  6  7  8  9 10 11]转置: [[ 0  4  8] [ 1  5  9] [ 2  6 10] [ 3  7 11]]增加维度: (1, 12)压缩维度: (12,)

3. 数组运算

3.1 数学运算

import numpy as npa = np.array([1, 2, 3])b = np.array([4, 5, 6])# 算术运算print("加法:", a + b)print("减法:", a - b)print("乘法:", a * b)    # 元素乘法,不是矩阵乘法print("除法:", a / b)print("幂运算:", a ** 2)# 比较运算print("相等:", a == b)print("大于:", a > 2)# 聚合函数print("总和:", np.sum(a))print("均值:", np.mean(a))print("标准差:", np.std(a))print("最大值:", np.max(a))print("最小值:", np.min(a))# 三角函数angles = np.array([0, np.pi/2, np.pi])print("正弦值:", np.sin(angles))

输出结果:

法: [5 7 9]减法: [-3 -3 -3]乘法: [ 4 10 18]除法: [0.25 0.4  0.5 ]幂运算: [1 4 9]相等: [False False False]大于: [False False  True]总和: 6均值: 2.0标准差: 0.816496580927726最大值: 3最小值: 1正弦值: [0.0000000e+00 1.0000000e+00 1.2246468e-16]

3.2 广播机制

import numpy as np# 标量与数组arr = np.array([[1, 2, 3], [4, 5, 6]])print("数组 + 标量:", arr + 10)# 不同形状数组vector = np.array([10, 20, 30])print("数组 + 向量:", arr + vector)# 广播规则示例a = np.array([[1], [2], [3]])  # 形状 (3, 1)b = np.array([10, 20, 30])     # 形状 (3,)print("广播加法:", a + b)

输出结果:

数组 + 标量: [[11 12 13] [14 15 16]]数组 + 向量: [[11 22 33] [14 25 36]]广播加法: [[11 21 31] [12 22 32] [13 23 33]]

4. 实用功能

4.1 文件操作

import numpy as np# 创建示例数据data = np.random.rand(5, 3)# 保存到文件np.savetxt('data.txt', data, delimiter=',')# 从文件加载loaded_data = np.loadtxt('data.txt', delimiter=',')print("从文件加载的数据:", loaded_data)# 二进制格式(更高效)np.save('data.npy', data)binary_loaded = np.load('data.npy')print("二进制加载的数据:", binary_loaded)

输出结果:

从文件加载的数据: [[0.4553778  0.49906932 0.97523208] [0.35906304 0.55012335 0.38348623] [0.29169913 0.90129311 0.22774977] [0.97325678 0.32749914 0.85698094] [0.82758157 0.36911462 0.42524159]]二进制加载的数据: [[0.4553778  0.49906932 0.97523208] [0.35906304 0.55012335 0.38348623] [0.29169913 0.90129311 0.22774977] [0.97325678 0.32749914 0.85698094] [0.82758157 0.36911462 0.42524159]]

4.2 随机数生成

import numpy as np# 设置随机种子(确保可重复性)np.random.seed(42)# 生成随机数uniform = np.random.rand(5)          # [0,1)均匀分布normal = np.random.randn(5)          # 标准正态分布integers = np.random.randint(0, 10, 5)  # 随机整数print("均匀分布:", uniform)print("正态分布:", normal)print("随机整数:", integers)# 随机抽样choices = np.random.choice(['A', 'B', 'C'], size=10, p=[0.5, 0.3, 0.2])print("随机选择:", choices)

输出结果:

匀分布: [0.37454012 0.95071431 0.73199394 0.59865848 0.15601864]正态分布: [ 0.27904129  1.01051528 -0.58087813 -0.52516981 -0.57138017]随机整数: [5 8 0 9 2]随机选择: ['A' 'C' 'A' 'C' 'B' 'A' 'A' 'C' 'B' 'A']

5. 基础应用示例

5.1 数据处理

import numpy as np# 创建示例数据集data = np.array([    [1, 2, 3, 4],    [5, 6, 7, 8],    [9, 10, 11, 12]])# 数据筛选filtered = data[data > 5]print("大于5的值:", filtered)# 条件修改data[data % 2 == 0] = -1  # 将所有偶数改为-1print("修改后的数据:", data)# 数据统计print("每列均值:", np.mean(data, axis=0))print("每行最大值:", np.max(data, axis=1))

输出结果:

大于5的值: [ 6  7  8  9 10 11 12]修改后的数据: [[ 1 -1  3 -1] [ 5 -1  7 -1] [ 9 -1 11 -1]]每列均值: [ 5. -1.  7. -1.]每行最大值: [ 3  7 11]

5.2 简单图形处理

import numpy as np# 模拟一个灰度图像(10x10像素)image = np.random.randint(0, 256, (10, 10))print("原始图像数据:", image)# 图像处理操作brightened = np.clip(image + 50, 0, 255)  # 增加亮度inverted = 255 - image                    # 颜色反转threshold = (image > 128).astype(int)     # 二值化print("亮度增强:", brightened)print("颜色反转:", inverted)print("二值化:", threshold)

输出结果:

 始图像数据: [[ 23 218 156  90 149 255 116 104   8  60] [ 70  42  74 180 227  17 189  92  11  90] [207  61 110 223  21 153  47 136  20 225] [  8  93 153  81  81  14 112 107 249  50] [160 149  95  60 214 233 149 247 127   7] [140 183  32  82 247 128 174  16  44 212] [ 34 203 210  89  98  59  48 200 181 111] [111  23  99 101 108 130  65 215 123 205] [170  93 210  84 230 213  82 126  87 247] [187 250   8 157  78  54  54 227  89 164]]亮度增强: [[ 73 255 206 140 199 255 166 154  58 110] [120  92 124 230 255  67 239 142  61 140] [255 111 160 255  71 203  97 186  70 255] [ 58 143 203 131 131  64 162 157 255 100] [210 199 145 110 255 255 199 255 177  57] [190 233  82 132 255 178 224  66  94 255] [ 84 253 255 139 148 109  98 250 231 161] [161  73 149 151 158 180 115 255 173 255] [220 143 255 134 255 255 132 176 137 255] [237 255  58 207 128 104 104 255 139 214]]颜色反转: [[232  37  99 165 106   0 139 151 247 195] [185 213 181  75  28 238  66 163 244 165] [ 48 194 145  32 234 102 208 119 235  30] [247 162 102 174 174 241 143 148   6 205] [ 95 106 160 195  41  22 106   8 128 248] [115  72 223 173   8 127  81 239 211  43] [221  52  45 166 157 196 207  55  74 144] [144 232 156 154 147 125 190  40 132  50] [ 85 162  45 171  25  42 173 129 168   8] [ 68   5 247  98 177 201 201  28 166  91]]二值化: [[0 1 1 0 1 1 0 0 0 0] [0 0 0 1 1 0 1 0 0 0] [1 0 0 1 0 1 0 1 0 1] [0 0 1 0 0 0 0 0 1 0] [1 1 0 0 1 1 1 1 0 0] [1 1 0 0 1 0 1 0 0 1] [0 1 1 0 0 0 0 1 1 0] [0 0 0 0 0 1 0 1 0 1] [1 0 1 0 1 1 0 0 0 1] [1 1 0 1 0 0 0 1 0 1]]

6. 性能调优和错误处理

6.1 性能优化

import numpy as np# 不好的做法:使用Python循环def slow_sum(arr):    result = 0    for x in arr:        result += x    return result# 好的做法:使用NumPy向量化操作def fast_sum(arr):    return np.sum(arr)# 测试性能large_arr = np.random.rand(1000000)import timestart = time.time()slow_result = slow_sum(large_arr)end = time.time()print(f"循环求和: {end - start:.6f}秒")start = time.time()fast_result = fast_sum(large_arr)end = time.time()print(f"向量化求和: {end - start:.6f}秒")

输出结果:

循环求和: 0.471191秒向量化求和: 0.003989秒

6.2 常见错误

import numpy as np# 错误:视图 vs 副本arr = np.array([1, 2, 3, 4])view = arr[1:3]    # 这是视图,修改会影响原数组copy = arr[1:3].copy()  # 这是副本,独立于原数组view[0] = 999print("原数组被修改:", arr)  # [1, 999, 3, 4]copy[0] = 888print("原数组不变:", arr)    # [1, 999, 3, 4]# 正确使用数据类型float_arr = np.array([1, 2, 3], dtype=np.float64)int_arr = np.array([1.5, 2.7, 3.1], dtype=np.int32)  # 注意会截断print("浮点数组:", float_arr)print("整数数组:", int_arr)  # [1, 2, 3]

输出结果:

原数组被修改: [  1 999   3   4]原数组不变: [  1 999   3   4]浮点数组: [1. 2. 3.]整数数组: [1 2 3]

6.3 小结

数组创建:np.array(), np.zeros(), np.ones(), np.arange(), np.linspace() 数组属性:.shape, .dtype, .ndim 索引和切片:基本索引、布尔索引、花式索引 数组操作:reshape(), concatenate(), stack() 数学运算:向量化运算、广播机制 通用函数:np.sin(), np.exp(), np.sqrt()等 线性代数:np.dot(), np.linalg.norm()

三、趣味示例

1. 井字棋游戏 – 理解二维数组

 import numpy as np# 创建游戏棋盘def create_board():    """    创建一个3x3的井字棋棋盘,初始状态为全0    返回值: 3x3的NumPy数组,数据类型为整数    0表示空位,1表示玩家X,2表示玩家O    """    # np.zeros((3, 3), dtype=int) 创建一个3行3列的全0数组    return np.zeros((3, 3), dtype=int)# 打印棋盘(美化输出)def print_board(board):    """    将数字表示的棋盘转换为可视化的字符格式并打印    参数:    board: 3x3的NumPy数组,表示当前棋盘状态    """    # 定义数字到符号的映射字典    # 0 -> 空格, 1 -> 'X', 2 -> 'O'    symbols = {0: ' ', 1: 'X', 2: 'O'}    # 遍历每一行    for i in range(3):        # 将当前行的数字转换为对应的符号        row = [symbols[board[i, j]] for j in range(3)]        # 使用' | '连接符号并打印,前面加空格使输出居中        print(' ' + ' | '.join(row))        # 如果不是最后一行,打印分隔线        if i < 2:            print('-----------')    print()  # 打印空行使输出更清晰# 检查胜利条件def check_win(board, player):    """    检查指定玩家是否获胜    参数:    board: 3x3的NumPy数组,表示当前棋盘状态    player: 整数,1表示玩家X,2表示玩家O    返回值:    布尔值,True表示该玩家获胜,False表示未获胜    """    # 检查所有行是否有获胜情况    # np.all() 检查给定轴上的所有元素是否为True    for i in range(3):        # 检查第i行是否全部由当前玩家的棋子占据        if np.all(board[i, :] == player):            return True    # 检查所有列是否有获胜情况    for j in range(3):        # 检查第j列是否全部由当前玩家的棋子占据        if np.all(board[:, j] == player):            return True    # 检查两条对角线是否有获胜情况    # np.diag() 获取矩阵的主对角线元素    # np.fliplr() 左右翻转矩阵,然后获取对角线即为反对角线    if np.all(np.diag(board) == player) or np.all(np.diag(np.fliplr(board)) == player):        return True    # 如果以上条件都不满足,则该玩家未获胜    return False# 游戏演示# 创建初始棋盘board = create_board()print("初始棋盘:")print_board(board)# 模拟几步游戏# 玩家X在左上角(0,0)位置落子board[0, 0] = 1  # X 在左上角# 玩家O在中心(1,1)位置落子board[1, 1] = 2  # O 在中心# 玩家X在上中(0,1)位置落子board[0, 1] = 1  # X 在上中print("游戏进行中:")print_board(board)# 检查玩家X是否获胜print("X 是否获胜?", check_win(board, 1))

输出结果:

初始棋盘:   |   |  -----------   |   |-----------   |   |游戏进行中: X | X |-----------   | O |-----------   |   |X 是否获胜? False

体现的知识点

np.zeros() 创建数组 二维数组索引 board[i, j] np.all() 检查所有元素是否满足条件 np.diag() 获取对角线元素 np.fliplr() 左右翻转数组

2. 蒙特卡洛方法估算π的动态可视化

import numpy as npimport matplotlib.pyplot as pltimport timefrom matplotlib.animation import FuncAnimationdef animated_monte_carlo(n_samples=10000, frame_interval=100):    """    创建蒙特卡洛方法估算π的动态可视化    参数:    n_samples: 总采样点数,默认10000个点    frame_interval: 每帧更新的点数,默认每100个点更新一次动画    返回:    matplotlib.animation.FuncAnimation对象,用于控制动画    """    # 生成所有随机点:在[-1, 1] x [-1, 1]的正方形区域内均匀采样    # points是一个n_samples x 2的数组,每行代表一个点的(x,y)坐标    points = np.random.uniform(-1, 1, size=(n_samples, 2))    # 计算每个点到原点(0,0)的距离    # 使用欧几里得距离公式:sqrt(x² + y²)    distances = np.sqrt(points[:, 0]**2 + points[:, 1]**2)    # 创建图形窗口,包含左右两个子图    # 左图显示随机点和单位圆,右图显示π估计值的收敛过程    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))    # 初始化左图的散点图(开始时没有点)    scatter = ax1.scatter([], [], s=1, alpha=0.5)  # 小点,半透明    ax1.set_xlim(-1, 1)    # 设置x轴范围    ax1.set_ylim(-1, 1)    # 设置y轴范围    ax1.set_aspect('equal') # 保持纵横比相等,确保圆看起来是圆形    # 在左图绘制单位圆(半径为1的圆)    # 这个圆用于可视化:圆内的点表示落在单位圆内    circle = plt.Circle((0, 0), 1, color='green', fill=False, linewidth=2)    ax1.add_patch(circle)  # 将圆添加到图中    # 初始化右图的收敛曲线(开始时没有数据)    line, = ax2.plot([], [], linewidth=1)    # 在右图添加一条水平线表示π的真实值    ax2.axhline(y=np.pi, color='r', linestyle='--', label='True π')    ax2.set_xlim(0, n_samples)  # 设置x轴范围(点数)    ax2.set_ylim(2.8, 3.4)      # 设置y轴范围(π的估计值范围)    ax2.set_xlabel('Number of points')    # x轴标签    ax2.set_ylabel('Estimate of π')       # y轴标签    ax2.set_title('Convergence of π Estimate')  # 右图标题    ax2.legend()    # 显示图例    ax2.grid(True)  # 显示网格    # 在左图添加文本框,显示当前点数、π估计值和误差    text = ax1.text(0.05, 0.95, '', transform=ax1.transAxes, fontsize=12,                   verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8))    # 动画更新函数 - 每一帧调用一次    def update(frame):        # 计算当前帧应该显示的点数        # 每frame_interval个点更新一次,但不超过总点数n_samples        n = min((frame + 1) * frame_interval, n_samples)        # 更新左图的散点图        # 确定哪些点落在单位圆内(距离<=1)        inside = distances[:n]  0 else 0        # 设置文本内容:点数、估计值和误差        text.set_text(f'Points: {n:,}Estimate: {current_estimate:.6f}Error: {abs(current_estimate - np.pi):.6f}')        # 返回需要更新的图形元素        return scatter, line, text    # 计算总帧数:总点数除以每帧更新的点数    frames = n_samples // frame_interval    # 创建动画对象    # fig: 动画所在的图形    # update: 更新函数    # frames: 总帧数    # interval: 帧间隔时间(毫秒)    # blit: 使用blitting技术优化动画(只重绘变化的部分)    ani = FuncAnimation(fig, update, frames=frames, interval=50, blit=True)    # 调整子图布局,避免重叠    plt.tight_layout()    # 显示动画    plt.show()    # 返回动画对象,以便后续控制(如保存为视频)    return ani# 运行动画# 使用10000个点,每100个点更新一次动画ani = animated_monte_carlo(n_samples=10000, frame_interval=100)

基本原理

这段代码实现了使用蒙特卡洛方法估算π值的动态可视化,其数学原理如下:

基本思想:在一个边长为2的正方形内随机撒点,统计落在内切圆(半径为1)内的点数 面积关系: 正方形面积 = 2 × 2 = 4 圆形面积 = π × 1² = π 概率估计:点在圆内的概率 = 圆形面积 / 正方形面积 = π/4 π估算公式:π ≈ 4 × (圆内点数 / 总点数) 代码亮点解析 向量化计算:使用NumPy一次性生成所有随机点并计算距离,避免了低效的Python循环 动态可视化:使用Matplotlib的动画功能实时展示估算过程 双视图设计:左侧显示随机点分布,右侧显示π估计值的收敛过程 性能优化: 使用blit=True只重绘变化的部分,提高动画性能 分批更新点(每100个点更新一次),平衡视觉效果和性能 信息丰富:实时显示当前点数、π估计值和误差,方便观察收敛过程

3. 图像滤镜 – 理解数组运算

构建AI智能体:AI数据科学NumPy — 不可不知、由点及面抽丝剥茧+趣味范例
import numpy as npfrom PIL import Imageimport matplotlib.pyplot as plt# 设置中文字体支持# 确保图表中的中文标题能够正确显示plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体显示中文plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题# 创建简单的测试图像def create_test_image():    """    创建一个自定义的渐变测试图像,用于演示图像处理效果    返回:    一个100x100像素的RGB图像,数据类型为uint8(0-255范围)    """    # 创建从0到1的等间距数组,用于x和y坐标    x = np.linspace(0, 1, 100)  # 100个点,从0到1    y = np.linspace(0, 1, 100)  # 100个点,从0到1    # 创建网格坐标矩阵    # xx的每一行都是x的复制,yy的每一列都是y的复制    xx, yy = np.meshgrid(x, y)    # 创建RGB三个通道的渐变效果    red = xx        # 红色通道:水平渐变(从左到右增强)    green = yy      # 绿色通道:垂直渐变(从下到上增强)    blue = (xx + yy) / 2  # 蓝色通道:对角线渐变(从右下到左上增强)    # 将三个通道堆叠成三维数组(高度×宽度×通道)    # 然后缩放到0-255范围并转换为8位无符号整数    image = np.stack([red, green, blue], axis=2)    return (image * 255).astype(np.uint8)# 定义彩虹色条纹的颜色值(RGB格式,范围0-1)colors = [    [1, 0, 0],    # 红色    [1, 0.5, 0],  # 橙色    [1, 1, 0],    # 黄色    [0, 1, 0],    # 绿色    [0, 0, 1],    # 蓝色    [0.5, 0, 0.5],# 紫色]# 创建彩虹色条纹图像def create_rainbow_stripes(size=100):    """    创建一个彩虹色条纹图像    参数:    size: 图像的大小(将创建size×size的正方形图像)    返回:    一个包含彩虹色条纹的RGB图像    """    # 创建一个全零的三维数组(高度×宽度×3个颜色通道)    image = np.zeros((size, size, 3))    # 计算每个条纹的宽度(将图像水平分成6等份)    stripe_width = size // len(colors)    # 填充彩虹色条纹    for i, color in enumerate(colors):        # 计算当前条纹的起始和结束列索引        start = i * stripe_width        end = (i + 1) * stripe_width if i < len(colors) - 1 else size        # 将当前条纹的所有行和指定列范围设置为当前颜色        image[:, start:end] = color    return image# 应用各种滤镜def apply_filters(image):    """    对输入图像应用多种滤镜效果    参数:    image: 输入图像(NumPy数组,uint8类型,0-255范围)    返回:    四个处理后的图像:灰度图、边缘检测图、颜色反转图、sepia色调图    """    # 将图像转换为浮点数并归一化到0-1范围,便于数学运算    img_float = image.astype(float) / 255.0    # 1. 灰度化:将彩色图像转换为灰度图像    # 方法:取RGB三个通道的平均值    gray = np.mean(img_float, axis=2)    # 2. 边缘检测(使用简化的Sobel算子)    # 定义Sobel算子的x方向和y方向卷积核    sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])  # 水平边缘检测    sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])  # 垂直边缘检测    # 初始化边缘强度图    edges = np.zeros_like(gray)    # 对每个颜色通道分别应用Sobel算子    for i in range(3):        # 获取当前颜色通道        channel = img_float[:, :, i]        # 使用卷积计算x方向和y方向的梯度        # 注意:这里使用了一维卷积,需要先将二维数组展平        gx = np.abs(np.convolve(channel.flatten(), sobel_x.flatten(), mode='same').reshape(channel.shape))        gy = np.abs(np.convolve(channel.flatten(), sobel_y.flatten(), mode='same').reshape(channel.shape))        # 计算梯度幅值并累加到边缘图中        edges += np.sqrt(gx**2 + gy**2)    # 对三个通道的结果取平均    edges = edges / 3.0    # 3. 颜色反转:用1减去每个像素值,实现颜色反转效果    inverted = 1.0 - img_float    # 4. Sepia色调(棕褐色调效果)    # 定义Sepia色调的转换矩阵    sepia_matrix = np.array([[0.393, 0.769, 0.189],   # 红色分量转换系数                           [0.349, 0.686, 0.168],     # 绿色分量转换系数                           [0.272, 0.534, 0.131]])    # 蓝色分量转换系数    # 应用矩阵乘法实现颜色转换    sepia = np.dot(img_float, sepia_matrix.T)    # 确保值在0-1范围内(使用np.clip防止溢出)    sepia = np.clip(sepia, 0, 1)    return gray, edges, inverted, sepia# 创建并处理图像# 生成测试图像image = create_test_image()# 应用各种滤镜gray, edges, inverted, sepia = apply_filters(image)# 创建彩虹色条纹图像rainbow_image = create_rainbow_stripes()# 显示结果# 创建2行3列的子图布局fig, axes = plt.subplots(2, 3, figsize=(15, 10))# 第一行第一列:原始图像axes[0, 0].imshow(image)axes[0, 0].set_title('原始图像')axes[0, 0].axis('off')  # 隐藏坐标轴# 第一行第二列:灰度化效果axes[0, 1].imshow(gray, cmap='gray')  # 使用灰度颜色映射axes[0, 1].set_title('灰度化')axes[0, 1].axis('off')# 第一行第三列:边缘检测效果axes[0, 2].imshow(edges, cmap='hot')  # 使用热力图颜色映射axes[0, 2].set_title('边缘检测')axes[0, 2].axis('off')# 第二行第一列:颜色反转效果axes[1, 0].imshow(inverted)axes[1, 0].set_title('颜色反转')axes[1, 0].axis('off')# 第二行第二列:Sepia色调效果axes[1, 1].imshow(sepia)axes[1, 1].set_title('Sepia色调')axes[1, 1].axis('off')# 第二行第三列:彩虹条纹图像axes[1, 2].imshow(rainbow_image)axes[1, 2].set_title('彩虹条纹')axes[1, 2].axis('off')# 自动调整子图参数,使之填充整个图像区域plt.tight_layout()# 显示图形plt.show()

体现的知识点

数组创建和形状操作 数学运算和广播 数组索引和切片 np.convolve() 卷积操作 np.clip() 限制数值范围 np.dot() 矩阵乘法

代码技术亮点

数组操作: 使用np.linspace, np.meshgrid创建坐标网格 广播机制: 在创建渐变图像时利用了NumPy的广播功能 矩阵运算: 在Sepia滤镜中使用矩阵乘法实现颜色转换 卷积操作: 在边缘检测中使用卷积计算图像梯度 数组索引和切片: 在创建彩虹条纹时使用切片操作高效赋值

四、总结

操作

代码示例

说明

创建数组

np.array([1,2,3])

从列表创建

全零数组

TextCortex TextCortex

AI写作能手,在几秒钟内创建内容。

TextCortex 62 查看详情 TextCortex

np.zeros((3,3))

创建全0数组

全一数组

np.ones((2,2))

创建全1数组

范围数组

np.arange(0,10,2)

创建等差数组

随机数组

np.random.rand(3,3)

创建随机数组

改变形状

arr.reshape(2,3)

改变数组形状

数组拼接

np.concatenate([a,b])

连接数组

数学运算

arr + 1, arr * 2

向量化运算

统计函数

np.mean(arr), np.std(arr)

统计计算

以上就是构建AI智能体:AI数据科学NumPy — 不可不知、由点及面抽丝剥茧+趣味范例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/985006.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
学信网登录总提示验证码错误怎么办_验证码错误解决
上一篇 2025年12月1日 21:13:50
CSS框架Foundation网格系统使用方法_多列布局技巧
下一篇 2025年12月1日 21:13:51

相关推荐

  • composer require-dev和require有什么不同_Composer Require与Require-Dev区别解析

    require用于声明项目运行必需的依赖,如框架、数据库组件和第三方SDK,这些包会随项目部署到生产环境;2. require-dev用于声明仅在开发和测试阶段需要的工具,如PHPUnit、PHPStan、Faker等,不会默认部署到生产环境;3. 安装时composer install根据环境决定…

    2026年5月10日
    1000
  • Matplotlib 地图中多类型图例的创建与优化

    Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化

    本教程旨在解决matplotlib地图可视化中,如何在一个图例中同时展示颜色块(如区域分类)和自定义标记(如特定兴趣点)的问题。文章详细介绍了当传统`patch`对象无法正确显示标记时,如何利用`matplotlib.lines.line2d`创建标记图例句柄,并将其与颜色块图例句柄合并,从而生成一…

    2026年5月10日 用户投稿
    100
  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    000
  • 利用海象运算符简化条件赋值:Python教程与最佳实践

    本文旨在探讨Python中海象运算符(:=)在条件赋值场景下的应用。通过对比传统if/else语句与海象运算符,以及条件表达式,分析海象运算符在简化代码、提高可读性方面的优势与局限性。并通过具体示例,展示如何在列表推导式等场景下合理使用海象运算符,同时强调其潜在的复杂性及替代方案,帮助开发者更好地掌…

    2026年5月10日
    100
  • Debian syslog性能优化技巧有哪些

    提升Debian系统syslog (通常基于rsyslog)性能,关键在于精简配置和高效处理日志。以下策略能有效优化日志管理,提升系统整体性能: 精简配置,高效加载: 在rsyslog配置文件中,仅加载必要的输入、输出和解析模块。 使用全局指令设置日志级别和格式,避免不必要的处理。 自定义模板: 创…

    2026年5月10日
    000
  • 怎么在PHP代码中实现图片上传功能_PHP图片上传功能实现与安全处理教程

    首先创建含enctype的HTML表单,再用PHP接收文件,检查目录、移动临时文件,验证类型与大小,生成唯一文件名,并调整php.ini限制以确保上传成功。 如果您尝试在PHP项目中添加图片上传功能,但服务器无法正确接收或保存文件,则可能是由于表单配置、文件处理逻辑或安全限制的问题。以下是实现该功能…

    2026年5月10日
    100
  • 比特币新手教程 比特币交易平台有哪些

    比特币是一种去中心化的数字货币,基于区块链技术实现点对点交易,具有匿名性、有限发行和不可篡改等特点;新手可通过交易所购买,P2P交易获得比特币,常用平台包括Binance、OKX和Huobi;交易流程包括注册账户、实名认证、绑定支付方式、充值法币并下单购买,可选择市价单或限价单;比特币存储方式有交易…

    2026年5月10日
    000
  • c++中的SFINAE技术是什么_c++模板编程中的SFINAE原理与应用

    SFINAE 是“替换失败不是错误”的原则,指模板实例化时若参数替换导致错误,只要存在其他合法候选,编译器不报错而是继续重载决议。它用于条件启用模板、类型检测等场景,如通过 decltype 或 enable_if 控制函数重载,实现类型特征判断。尽管 C++20 引入 Concepts 简化了部分…

    2026年5月10日
    000
  • Go语言mgo查询构建:深入理解bson.M与日期范围查询的正确实践

    本文旨在解决go语言mgo库中构建复杂查询时,特别是涉及嵌套`bson.m`和日期范围筛选的常见错误。我们将深入剖析`bson.m`的类型特性,解释为何直接索引`interface{}`会导致“invalid operation”错误,并提供一种推荐的、结构清晰的代码重构方案,以确保查询条件能够正确…

    2026年5月10日
    100
  • RichHandler与Rich Progress集成:解决显示冲突的教程

    在使用rich库的`richhandler`进行日志输出并同时使用`progress`组件时,可能会遇到显示错乱或溢出问题。这通常是由于为`richhandler`和`progress`分别创建了独立的`console`实例导致的。解决方案是确保日志处理器和进度条组件共享同一个`console`实例…

    2026年5月10日
    000
  • Golang goroutine与channel调试技巧

    使用go run -race检测数据竞争,结合runtime.NumGoroutine监控协程数量,通过pprof分析阻塞调用栈,利用select超时避免永久阻塞,有效排查goroutine泄漏、死锁和数据竞争问题。 Go语言的goroutine和channel是并发编程的核心,但它们也带来了调试上…

    2026年5月10日
    000
  • 《魔兽世界》将于6月11日开启国服回归技术测试

    《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试

    《%ign%ignore_a_1%re_a_1%》官方宣布,将于6月11日开启国服回归技术测试,时间为7天,并称可以在6月内正式开服,玩家们可以访问官网下载战网客户端并预下载“巫妖王之怒”客户端,技术测试详情见下图。 WordAi WordAI是一个AI驱动的内容重写平台 53 查看详情 以上就是《…

    2026年5月10日 用户投稿
    200
  • 使用 Jupyter Notebook 进行探索性数据分析

    Jupyter Notebook通过单元格实现代码与Markdown结合,支持数据导入(pandas)、清洗(fillna)、探索(matplotlib/seaborn可视化)、统计分析(describe/corr)和特征工程,便于记录与分享分析过程。 Jupyter Notebook 是进行探索性…

    2026年5月10日
    000
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    100
  • 网站标题关键词更新后,搜索引擎为何仍显示旧标题?

    网站标题更新后,搜索引擎为何显示旧标题? 网站SEO优化中,站长常修改网站标题关键词,期望搜索结果显示自定义标题。然而,即使更新标签、meta keywords、meta description和结构化数据中的name属性后,搜索结果仍显示旧标题,这令人费解。本文将对此进行解释。 问题:站长修改了网…

    2026年5月10日
    100
  • 创建指定大小并填充特定数据的Golang文件教程

    本文将介绍如何使用Golang创建一个指定大小的文件,并用特定数据填充它。我们将使用 `os` 包提供的函数来创建和截断文件,从而实现快速生成大文件的目的。示例代码展示了如何创建一个10MB的文件,并将其填充为全零数据。掌握这些方法,可以方便地在例如日志系统或磁盘队列等场景中,预先创建测试文件或初始…

    2026年5月10日
    000
  • Python命令怎样使用profile分析脚本性能 Python命令性能分析的基础教程

    使用Python的cProfile模块分析脚本性能最直接的方式是通过命令行执行python -m cProfile your_script.py,它会输出每个函数的调用次数、总耗时、累积耗时等关键指标,帮助定位性能瓶颈;为进一步分析,可将结果保存为文件python -m cProfile -o ou…

    2026年5月10日
    000
  • 如何插入查询结果数据_SQL插入Select查询结果方法

    如何插入查询结果数据_SQL插入Select查询结果方法如何插入查询结果数据_SQL插入Select查询结果方法如何插入查询结果数据_SQL插入Select查询结果方法如何插入查询结果数据_SQL插入Select查询结果方法

    使用INSERT INTO…SELECT语句可高效插入数据,通过NOT EXISTS、LEFT JOIN、MERGE语句或唯一约束避免重复;表结构不一致时可通过别名、类型转换、默认值或计算字段处理;结合存储过程可提升可维护性,支持参数化与动态SQL。 将查询结果数据插入到另一个表中,可以…

    2026年5月10日 用户投稿
    000
  • 使用 WebCodecs VideoDecoder 实现精确逐帧回退

    本文档旨在解决在使用 WebCodecs VideoDecoder 进行视频解码时,实现精确逐帧回退的问题。通过比较帧的时间戳与目标帧的时间戳,可以避免渲染中间帧,从而提高用户体验。本文将提供详细的解决方案和示例代码,帮助开发者实现精确的视频帧控制。 在使用 WebCodecs VideoDecod…

    2026年5月10日
    000
  • Discord.py 交互按钮超时与持久化解决方案

    本教程旨在解决Discord.py中交互按钮在一段时间后出现“This Interaction Failed”错误的问题。我们将深入探讨视图(View)的超时机制,并提供通过正确设置timeout参数以及利用bot.add_view()方法实现按钮持久化的具体方案,确保您的机器人交互功能稳定可靠,即…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信