构建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:12:25
下一篇 2025年12月1日 21:14:01

相关推荐

  • Uniapp 中如何不拉伸不裁剪地展示图片?

    灵活展示图片:如何不拉伸不裁剪 在界面设计中,常常需要以原尺寸展示用户上传的图片。本文将介绍一种在 uniapp 框架中实现该功能的简单方法。 对于不同尺寸的图片,可以采用以下处理方式: 极端宽高比:撑满屏幕宽度或高度,再等比缩放居中。非极端宽高比:居中显示,若能撑满则撑满。 然而,如果需要不拉伸不…

    2025年12月24日
    400
  • 如何让小说网站控制台显示乱码,同时网页内容正常显示?

    如何在不影响用户界面的情况下实现控制台乱码? 当在小说网站上下载小说时,大家可能会遇到一个问题:网站上的文本在网页内正常显示,但是在控制台中却是乱码。如何实现此类操作,从而在不影响用户界面(UI)的情况下保持控制台乱码呢? 答案在于使用自定义字体。网站可以通过在服务器端配置自定义字体,并通过在客户端…

    2025年12月24日
    800
  • 如何在地图上轻松创建气泡信息框?

    地图上气泡信息框的巧妙生成 地图上气泡信息框是一种常用的交互功能,它简便易用,能够为用户提供额外信息。本文将探讨如何借助地图库的功能轻松创建这一功能。 利用地图库的原生功能 大多数地图库,如高德地图,都提供了现成的信息窗体和右键菜单功能。这些功能可以通过以下途径实现: 高德地图 JS API 参考文…

    2025年12月24日
    400
  • 如何使用 scroll-behavior 属性实现元素scrollLeft变化时的平滑动画?

    如何实现元素scrollleft变化时的平滑动画效果? 在许多网页应用中,滚动容器的水平滚动条(scrollleft)需要频繁使用。为了让滚动动作更加自然,你希望给scrollleft的变化添加动画效果。 解决方案:scroll-behavior 属性 要实现scrollleft变化时的平滑动画效果…

    2025年12月24日
    000
  • 如何为滚动元素添加平滑过渡,使滚动条滑动时更自然流畅?

    给滚动元素平滑过渡 如何在滚动条属性(scrollleft)发生改变时为元素添加平滑的过渡效果? 解决方案:scroll-behavior 属性 为滚动容器设置 scroll-behavior 属性可以实现平滑滚动。 html 代码: click the button to slide right!…

    2025年12月24日
    500
  • 如何选择元素个数不固定的指定类名子元素?

    灵活选择元素个数不固定的指定类名子元素 在网页布局中,有时需要选择特定类名的子元素,但这些元素的数量并不固定。例如,下面这段 html 代码中,activebar 和 item 元素的数量均不固定: *n *n 如果需要选择第一个 item元素,可以使用 css 选择器 :nth-child()。该…

    2025年12月24日
    200
  • 使用 SVG 如何实现自定义宽度、间距和半径的虚线边框?

    使用 svg 实现自定义虚线边框 如何实现一个具有自定义宽度、间距和半径的虚线边框是一个常见的前端开发问题。传统的解决方案通常涉及使用 border-image 引入切片图片,但是这种方法存在引入外部资源、性能低下的缺点。 为了避免上述问题,可以使用 svg(可缩放矢量图形)来创建纯代码实现。一种方…

    2025年12月24日
    100
  • 如何解决本地图片在使用 mask JS 库时出现的跨域错误?

    如何跨越localhost使用本地图片? 问题: 在本地使用mask js库时,引入本地图片会报跨域错误。 解决方案: 要解决此问题,需要使用本地服务器启动文件,以http或https协议访问图片,而不是使用file://协议。例如: python -m http.server 8000 然后,可以…

    2025年12月24日
    200
  • 如何让“元素跟随文本高度,而不是撑高父容器?

    如何让 元素跟随文本高度,而不是撑高父容器 在页面布局中,经常遇到父容器高度被子元素撑开的问题。在图例所示的案例中,父容器被较高的图片撑开,而文本的高度没有被考虑。本问答将提供纯css解决方案,让图片跟随文本高度,确保父容器的高度不会被图片影响。 解决方法 为了解决这个问题,需要将图片从文档流中脱离…

    2025年12月24日
    000
  • 为什么 CSS mask 属性未请求指定图片?

    解决 css mask 属性未请求图片的问题 在使用 css mask 属性时,指定了图片地址,但网络面板显示未请求获取该图片,这可能是由于浏览器兼容性问题造成的。 问题 如下代码所示: 立即学习“前端免费学习笔记(深入)”; icon [data-icon=”cloud”] { –icon-cl…

    2025年12月24日
    200
  • 如何利用 CSS 选中激活标签并影响相邻元素的样式?

    如何利用 css 选中激活标签并影响相邻元素? 为了实现激活标签影响相邻元素的样式需求,可以通过 :has 选择器来实现。以下是如何具体操作: 对于激活标签相邻后的元素,可以在 css 中使用以下代码进行设置: li:has(+li.active) { border-radius: 0 0 10px…

    2025年12月24日
    100
  • 如何模拟Windows 10 设置界面中的鼠标悬浮放大效果?

    win10设置界面的鼠标移动显示周边的样式(探照灯效果)的实现方式 在windows设置界面的鼠标悬浮效果中,光标周围会显示一个放大区域。在前端开发中,可以通过多种方式实现类似的效果。 使用css 使用css的transform和box-shadow属性。通过将transform: scale(1.…

    2025年12月24日
    200
  • 为什么我的 Safari 自定义样式表在百度页面上失效了?

    为什么在 Safari 中自定义样式表未能正常工作? 在 Safari 的偏好设置中设置自定义样式表后,您对其进行测试却发现效果不同。在您自己的网页中,样式有效,而在百度页面中却失效。 造成这种情况的原因是,第一个访问的项目使用了文件协议,可以访问本地目录中的图片文件。而第二个访问的百度使用了 ht…

    2025年12月24日
    000
  • 如何用前端实现 Windows 10 设置界面的鼠标移动探照灯效果?

    如何在前端实现 Windows 10 设置界面中的鼠标移动探照灯效果 想要在前端开发中实现 Windows 10 设置界面中类似的鼠标移动探照灯效果,可以通过以下途径: CSS 解决方案 DEMO 1: Windows 10 网格悬停效果:https://codepen.io/tr4553r7/pe…

    2025年12月24日
    000
  • 使用CSS mask属性指定图片URL时,为什么浏览器无法加载图片?

    css mask属性未能加载图片的解决方法 使用css mask属性指定图片url时,如示例中所示: mask: url(“https://api.iconify.design/mdi:apple-icloud.svg”) center / contain no-repeat; 但是,在网络面板中却…

    2025年12月24日
    000
  • 如何用CSS Paint API为网页元素添加时尚的斑马线边框?

    为元素添加时尚的斑马线边框 在网页设计中,有时我们需要添加时尚的边框来提升元素的视觉效果。其中,斑马线边框是一种既醒目又别致的设计元素。 实现斜向斑马线边框 要实现斜向斑马线间隔圆环,我们可以使用css paint api。该api提供了强大的功能,可以让我们在元素上绘制复杂的图形。 立即学习“前端…

    2025年12月24日
    000
  • 图片如何不撑高父容器?

    如何让图片不撑高父容器? 当父容器包含不同高度的子元素时,父容器的高度通常会被最高元素撑开。如果你希望父容器的高度由文本内容撑开,避免图片对其产生影响,可以通过以下 css 解决方法: 绝对定位元素: .child-image { position: absolute; top: 0; left: …

    2025年12月24日
    000
  • 使用 Mask 导入本地图片时,如何解决跨域问题?

    跨域疑难:如何解决 mask 引入本地图片产生的跨域问题? 在使用 mask 导入本地图片时,你可能会遇到令人沮丧的跨域错误。为什么会出现跨域问题呢?让我们深入了解一下: mask 框架假设你以 http(s) 协议加载你的 html 文件,而当使用 file:// 协议打开本地文件时,就会产生跨域…

    2025年12月24日
    200
  • CSS 帮助

    我正在尝试将文本附加到棕色框的左侧。我不能。我不知道代码有什么问题。请帮助我。 css .hero { position: relative; bottom: 80px; display: flex; justify-content: left; align-items: start; color:…

    2025年12月24日 好文分享
    200
  • 前端代码辅助工具:如何选择最可靠的AI工具?

    前端代码辅助工具:可靠性探讨 对于前端工程师来说,在HTML、CSS和JavaScript开发中借助AI工具是司空见惯的事情。然而,并非所有工具都能提供同等的可靠性。 个性化需求 关于哪个AI工具最可靠,这个问题没有一刀切的答案。每个人的使用习惯和项目需求各不相同。以下是一些影响选择的重要因素: 立…

    2025年12月24日
    000

发表回复

登录后才能评论
关注微信