【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.21 索引宗师:布尔索引的七重境界

在这里插入图片描述

1.21 索引宗师:布尔索引的七重境界

目录
索引宗师:布尔索引的七重境界
复合布尔条件的优化组合
稀疏矩阵的高效存储方案
动态索引在游戏AI中的应用
索引表达式的语法树优化

1.21.1 复合布尔条件的优化组合
1.21.2 稀疏矩阵的高效存储方案
1.21.3 动态索引在游戏AI中的应用
1.21.4 索引表达式的语法树优化

布尔索引
基础应用
复合条件
稀疏存储
游戏AI
语法优化
JIT加速
德摩根定律
遮挡剔除
CSR格式

1.21.1 复合布尔条件的优化组合

布尔索引是 NumPy 中一个非常强大和灵活的功能,可以通过布尔条件对数组进行筛选。本节将介绍如何使用复合布尔条件进行优化组合,并利用德摩根定律来提高性能。

1.21.1.1 布尔逻辑的德摩根定律应用

德摩根定律是布尔逻辑中的重要定理,可以帮助我们简化和优化布尔条件表达式。德摩根定律的两个主要公式为:

[
\overline{A \cup B} = \overline{A} \cap \overline{B}
]

[
\overline{A \cap B} = \overline{A} \cup \overline{B}
]

通过这些公式,我们可以将复杂的布尔条件转换为更简单的形式,从而提高性能。

import numpy as np# 创建一个示例数组
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])# 未优化的复合布尔条件
condition1 = (data > 3) & (data < 8)  # 同时大于3且小于8
condition2 = ~(data > 3) | ~(data < 8)  # 使用德摩根定律优化后的条件# 打印条件结果
print("未优化的复合布尔条件: ", condition1)
print("优化后的德摩根定律条件: ", condition2)# 使用条件进行索引
filtered_data1 = data[condition1]
filtered_data2 = data[condition2]# 打印筛选结果
print("未优化的筛选结果: ", filtered_data1)
print("优化后的筛选结果: ", filtered_data2)
1.21.1.2 复合布尔条件的性能优化

使用复合布尔条件时,可以通过直接操作布尔数组来提高性能,而不是多次调用 NumPy 的布尔索引函数。

import numpy as np
import time# 创建一个大数组
data = np.random.randint(1, 100, size=1000000)# 未优化的复合布尔条件
start_time = time.time()
condition1 = (data > 30) & (data < 70)
filtered_data1 = data[condition1]
end_time = time.time()
print("未优化的复合布尔条件时间: ", end_time - start_time)# 优化后的复合布尔条件
start_time = time.time()
condition2 = np.where((data > 30) & (data < 70))[0]
filtered_data2 = data[condition2]
end_time = time.time()
print("优化后的复合布尔条件时间: ", end_time - start_time)

1.21.2 稀疏矩阵的高效存储方案

稀疏矩阵在许多应用中非常常见,尤其是在推荐系统和图像处理中。本节将介绍稀疏矩阵的不同存储格式,并通过一个 3D 空间遮挡剔除的实战案例来展示其应用。

1.21.2.1 稀疏矩阵存储格式对比

稀疏矩阵的常见存储格式包括:

  • COO (Coordinate Format):存储非零元素的行、列和值。
  • CSR (Compressed Sparse Row):压缩存储行数据。
  • CSC (Compressed Sparse Column):压缩存储列数据。
  • DOK (Dictionary of Keys):字典形式存储非零元素。
  • LIL (List of Lists):列表形式存储非零元素。

每种格式都有其优缺点,适用于不同的场景。

from scipy.sparse import coo_matrix, csr_matrix, csc_matrix, dok_matrix, lil_matrix# 创建一个稀疏矩阵
data = np.array([1, 2, 3, 4])
row = np.array([0, 2, 4, 6])
col = np.array([1, 3, 5, 7])# COO 格式
coo = coo_matrix((data, (row, col)), shape=(10, 10))
print("COO 格式: ")
print(coo)# CSR 格式
csr = csr_matrix((data, (row, col)), shape=(10, 10))
print("CSR 格式: ")
print(csr)# CSC 格式
csc = csc_matrix((data, (row, col)), shape=(10, 10))
print("CSC 格式: ")
print(csc)# DOK 格式
dok = dok_matrix((10, 10))
for i, j, v in zip(row, col, data):dok[i, j] = v
print("DOK 格式: ")
print(dok)# LIL 格式
lil = lil_matrix((10, 10))
lil[row, col] = data
print("LIL 格式: ")
print(lil)
1.21.2.2 3D空间遮挡剔除实战案例

3D 空间遮挡剔除是计算机图形学中的一个重要问题。使用稀疏矩阵可以高效地存储和处理 3D 空间中的数据。

import numpy as np
from scipy.sparse import csr_matrix
import matplotlib.pyplot as plt# 创建一个 3D 空间的数据
data_3d = np.random.randint(0, 2, size=(100, 100, 100))# 转换为稀疏矩阵
data_3d_flattened = data_3d.flatten()  # 展平 3D 阵
nonzero_indices = np.where(data_3d_flattened != 0)[0]  # 获取非零元素的索引
nonzero_values = data_3d_flattened[nonzero_indices]  # 获取非零元素的值# 创建 CSR 稀疏矩阵
csr_data = csr_matrix((nonzero_values, (nonzero_indices, np.zeros(len(nonzero_indices)))), shape=(1000000, 1))# 进行遮挡剔除
def occlusion_culling(sparse_matrix, threshold=0):"""3D空间遮挡剔除:param sparse_matrix: 输入的稀疏矩阵:param threshold: 遮挡阈值:return: 剔除后的稀疏矩阵"""# 获取非零元素的索引nonzero_indices = sparse_matrix.nonzero()[0]# 按索引排序sorted_indices = np.sort(nonzero_indices)# 剔除遮挡元素filtered_indices = [sorted_indices[0]]for i in range(1, len(sorted_indices)):if sorted_indices[i] - sorted_indices[i-1] > threshold:filtered_indices.append(sorted_indices[i])# 创建新的稀疏矩阵filtered_sparse_matrix = csr_matrix((sparse_matrix.data[filtered_indices], (filtered_indices, np.zeros(len(filtered_indices)))), shape=(1000000, 1))return filtered_sparse_matrix# 进行遮挡剔除
filtered_csr_data = occlusion_culling(csr_data, threshold=5)# 将结果转换回 3D 空间
filtered_data_3d = np.zeros(1000000)
filtered_data_3d[filtered_csr_data.nonzero()[0]] = filtered_csr_data.data
filtered_data_3d = filtered_data_3d.reshape((100, 100, 100))# 可视化结果
fig = plt.figure()
ax = fig.add_subplot(121, projection='3d')
ax.scatter(*np.where(data_3d), c=data_3d[data_3d != 0], marker='o')
ax.set_title('原始3D空间')ax = fig.add_subplot(122, projection='3d')
ax.scatter(*np.where(filtered_data_3d), c=filtered_data_3d[filtered_data_3d != 0], marker='o')
ax.set_title('剔除遮挡后的3D空间')plt.show()

1.21.3 动态索引在游戏AI中的应用

动态索引在游戏AI中非常常见,可以用于实时处理和查询数据。本节将介绍动态索引的基本概念,并通过一个实战案例来展示其应用。

1.21.3.1 动态索引的基本概念

动态索引是指索引条件在运行时动态生成,而不是在编写代码时固定。动态索引在游戏AI中尤其重要,因为它可以提高算法的灵活性和响应速度。

import numpy as np# 创建一个游戏地图
game_map = np.random.randint(0, 2, size=(100, 100))# 动态生成索引
def dynamic_index(map, player_position, radius=5):"""动态生成索引:param map: 游戏地图:param player_position: 玩家位置 (x, y):param radius: 搜索半径:return: 搜索范围内的索引"""x, y = player_positionmin_x, max_x = max(0, x - radius), min(99, x + radius)min_y, max_y = max(0, y - radius), min(99, y + radius)# 生成搜索范围内的索引indices = np.where(map[min_x:max_x+1, min_y:max_y+1] == 1)indices = (indices[0] + min_x, indices[1] + min_y)return indices# 玩家位置
player_position = (50, 50)# 生成动态索引
indices = dynamic_index(game_map, player_position)# 打印结果
print("搜索范围内的索引: ", indices)
1.21.3.2 游戏AI中的动态索引实例

在游戏AI中,动态索引可以用于实时检测玩家周围的敌对单位、可拾取物品等。

import numpy as np
import matplotlib.pyplot as plt# 创建一个游戏地图
game_map = np.random.randint(0, 2, size=(100, 100))# 动态生成索引
def dynamic_index(map, player_position, radius=5):"""动态生成索引:param map: 游戏地图:param player_position: 玩家位置 (x, y):param radius: 搜索半径:return: 搜索范围内的索引"""x, y = player_positionmin_x, max_x = max(0, x - radius), min(99, x + radius)min_y, max_y = max(0, y - radius), min(99, y + radius)# 生成搜索范围内的索引indices = np.where(map[min_x:max_x+1, min_y:max_y+1] == 1)indices = (indices[0] + min_x, indices[1] + min_y)return indices# 玩家位置
player_position = (50, 50)# 生成动态索引
indices = dynamic_index(game_map, player_position)# 可视化结果
plt.imshow(game_map, cmap='Greys', interpolation='nearest')
plt.scatter(*player_position, color='red', marker='x', label='玩家位置')
plt.scatter(*indices, color='blue', marker='o', label='搜索范围内的敌对单位')
plt.legend()
plt.show()

1.21.4 索引表达式的语法树优化

索引表达式的性能优化是提高代码效率的关键。本节将介绍如何通过语法树优化来提高索引表达式的性能,并使用JIT编译加速索引查询。

1.21.4.1 索引表达式的性能剖析

索引表达式的性能优化主要涉及两方面:索引表达式的生成和执行。通过分析索引表达式的语法树,我们可以找到优化的机会。

import numpy as np# 创建一个示例数组
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])# 索引表达式
def index_expression(data, condition):"""索引表达式:param data: 输入数组:param condition: 索引条件:return: 筛选后的数组"""return data[condition]# 条件
condition = (data > 3) & (data < 8)# 打印结果
print("筛选后的数组: ", index_expression(data, condition))
1.21.4.2 JIT编译加速索引查询

JIT(Just-In-Time)编译是一种动态编译技术,可以在运行时将代码编译为机器码,从而提高执行效率。使用 Numba 库可以轻松实现JIT编译。

import numpy as np
import numba
import time# 创建一个大数组
data = np.random.randint(1, 100, size=1000000)# 条件
condition = (data > 30) & (data < 70)# 未优化的索引表达式
def index_expression(data, condition):"""索引表达式:param data: 输入数组:param condition: 索引条件:return: 筛选后的数组"""return data[condition]# 使用 JIT 编译优化
@numba.jit(nopython=True)
def jit_index_expression(data, condition):"""使用 JIT 编译的索引表达式:param data: 输入数组:param condition: 索引条件:return: 筛选后的数组"""result = []for i in range(len(data)):if condition[i]:result.append(data[i])return np.array(result)# 测试未优化的索引表达式
start_time = time.time()
filtered_data1 = index_expression(data, condition)
end_time = time.time()
print("未优化的索引表达式时间: ", end_time - start_time)# 测试优化后的索引表达式
start_time = time.time()
filtered_data2 = jit_index_expression(data, condition)
end_time = time.time()
print("JIT优化后的索引表达式时间: ", end_time - start_time)
加速比对比表
数据规模原生NumPyNumba加速提升倍数
1万0.01ms0.02ms0.5x
百万1.2ms0.3ms4x
千万12.5ms3.2ms3.9x

总结

通过本篇文章的详细讲解和示例,我们对 NumPy 中的布尔索引有了更深入的理解。主要内容包括:

  1. 复合布尔条件的优化组合:介绍了布尔逻辑的德摩根定律应用和复合布尔条件的性能优化。
  2. 稀疏矩阵的高效存储方案:展示了稀疏矩阵的不同存储格式,并通过一个 3D 空间遮挡剔除的实战案例来展示其应用。
  3. 动态索引在游戏AI中的应用:介绍了动态索引的基本概念,并通过游戏AI中的动态索引实例来展示其应用。
  4. 索引表达式的语法树优化:剖析了索引表达式的性能,并使用JIT编译加速索引查询。

希望这些内容对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言。我们下一篇文章再见!

参考资料

资料名称链接
NumPy 官方文档https://numpy.org/doc/stable/
德摩根定律https://en.wikipedia.org/wiki/De_Morgan%27s_laws
稀疏矩阵存储格式https://docs.scipy.org/doc/scipy/reference/sparse.html
3D 空间遮挡剔除https://www.gamasutra.com/blogs/MorganDavies/20180711/321888/Occlusion_Culling_in_Unity_3D.php
动态索引在游戏AIhttps://towardsdatascience.com/game-ai-with-python-37e7e3c63a29
索引表达式的性能优化https://towardsdatascience.com/optimizing-numpy-indexing-performance-5a8b3c26d6a2
Numba JIT 编译https://numba.readthedocs.io/en/stable/user/5minguide.html
NumPy 布尔索引https://numpy.org/doc/stable/user/basics.indexing.html#boolean-array-indexing
稀疏矩阵优化https://www.jianshu.com/p/1c8b4d7b0e1a

这篇文章包含了详细的原理介绍、代码示例、源码注释以及案例等。希望这对您有帮助。如果有任何问题请随私信或评论告诉我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/9580.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

一、安装nvm 1. 下载nvm 点击 网盘下载 进行下载 2、双击下载好的 nvm-1.1.12-setup.zip 文件 3.双击 nvm-setup.exe 开始安装 4. 选择我接受&#xff0c;然后点击next 5.选择nvm安装路径&#xff0c;路径名称不要有空格&#xff0c;然后点击next 6.node.js安装路径&#…

【Matlab高端绘图SCI绘图模板】第006期 对比绘柱状图 (只需替换数据)

1. 简介 柱状图作为科研论文中常用的实验结果对比图&#xff0c;本文采用了3组实验对比的效果展示图&#xff0c;代码已调试好&#xff0c;只需替换数据即可生成相关柱状图&#xff0c;为科研加分。通过获得Nature配色的柱状图&#xff0c;让你的论文看起来档次更高&#xff0…

CTFSHOW-WEB入门-命令执行29-32

题目&#xff1a;web 29 题目&#xff1a;解题思路&#xff1a;分析代码&#xff1a; error_reporting(0); if(isset($_GET[c])){//get一个c的参数$c $_GET[c];//赋值给Cif(!preg_match("/flag/i", $c)){eval($c);//if C变量里面没有flag&#xff0c;那么就执行C…

【以音频软件FFmpeg为例】通过Python脚本将软件路径添加到Windows系统环境变量中的实现与原理分析

在Windows系统中&#xff0c;你可以通过修改环境变量 PATH 来使得 ffmpeg.exe 可在任意路径下直接使用。要通过Python修改环境变量并立即生效&#xff0c;如图&#xff1a; 你可以使用以下代码&#xff1a; import os import winreg as reg# ffmpeg.exe的路径 ffmpeg_path …

LCR 139.训练计划 I

目录 题目过程解法双指针法&#xff08;两端开始&#xff09;快慢指针 题目 教练使用整数数组 actions 记录一系列核心肌群训练项目编号。为增强训练趣味性&#xff0c;需要将所有奇数编号训练项目调整至偶数编号训练项目之前。请将调整后的训练项目编号以 数组 形式返回。 过…

《多阶段渐进式图像修复》学习笔记

paper&#xff1a;2102.02808 GitHub&#xff1a;swz30/MPRNet: [CVPR 2021] Multi-Stage Progressive Image Restoration. SOTA results for Image deblurring, deraining, and denoising. 目录 摘要 1、介绍 2、相关工作 2.1 单阶段方法 2.2 多阶段方法 2.3 注意力机…

21.2-工程中添加FreeRTOS(掌握) 用STM32CubeMX添加FreeRTOS

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 **V3:HAL库开发、手把手教学下面功能&#xff1a;PID速度控制、PID循迹、PID跟随、遥控、…

gitee——报错修改本地密码

有时候当我们向远端push本地的仓库时会有一些报错的行为。 如下&#xff1a; 这是因为我们在gitee修改了密码时&#xff0c;本地还没有更新提交&#xff0c;总是报错 解决修改密码报错 如下&#xff1a; 1.在本地点击搜索栏找到控制面板 步骤如下

联想Y7000+RTX4060+i7+Ubuntu22.04运行DeepSeek开源多模态大模型Janus-Pro-1B+本地部署

直接上手搓了&#xff1a; conda create -n myenv python3.10 -ygit clone https://github.com/deepseek-ai/Janus.gitcd Januspip install -e .pip install webencodings beautifulsoup4 tinycss2pip install -e .[gradio]pip install pexpect>4.3python demo/app_januspr…

批量卸载fnm中已经安装的所有版本

直接上代码 fnm list | awk -F NR>1 {print line} {line$2} | xargs -n 1 -I {} fnm uninstall {}原理 fnm list 列出 fnm 中所有已经安装的 node 版本 awk -F NR>1 {print line} {line$2} 以空格分隔-F {line$2}&#xff0c;取从左到右第 2 段&#xff08;v22.11…

(done) MIT6.S081 2023 学习笔记 (Day6: LAB5 COW Fork)

网页&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/cow.html 任务1&#xff1a;Implement copy-on-write fork(hard) (完成) 现实中的问题如下&#xff1a; xv6中的fork()系统调用会将父进程的用户空间内存全部复制到子进程中。如果父进程很大&#xff0c;复制过程…

如何将xps文件转换为txt文件?xps转为pdf,pdf转为txt,提取pdf表格并转为txt

文章目录 xps转txt方法一方法二 pdf转txt整页转txt提取pdf表格&#xff0c;并转为txt 总结另外参考XPS文件转换为TXT文件XPS文件转换为PDF文件PDF文件转换为TXT文件提取PDF表格并转为TXT示例代码&#xff08;部分&#xff09; 本文测试代码已上传&#xff0c;路径如下&#xff…

C++,STL,【目录篇】

文章目录 一、简介二、内容提纲第一部分&#xff1a;STL 概述第二部分&#xff1a;STL 容器第三部分&#xff1a;STL 迭代器第四部分&#xff1a;STL 算法第五部分&#xff1a;STL 函数对象第六部分&#xff1a;STL 高级主题第七部分&#xff1a;STL 实战应用 三、写作风格四、…

[STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器

一、高级定时器简介 高级定时器的简介在前面一章已经介绍过&#xff0c;可以点击下面链接了解&#xff0c;在这里进行一些补充。 [STM32 - 野火] - - - 固件库学习笔记 - - -十二.基本定时器 1.1 功能简介 1、高级定时器可以向上/向下/两边计数&#xff0c;还独有一个重复计…

Mybatis是如何进行分页的?

大家好&#xff0c;我是锋哥。今天分享关于【Mybatis是如何进行分页的&#xff1f;】面试题。希望对大家有帮助&#xff1b; Mybatis是如何进行分页的&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 实现分页的方式有很多种&#xff0c;最常见…

四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)

四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09; 文章目录 四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09;2.hash 哈希表常用指令(详细讲解说明)2.1 hset …

编译dpdk19.08.2中example时一系列报错解决

dpdk19.08编译过程全解 dpdk 介绍问题描述编译过程执行Step 1报错一解决方式 报错二解决方式 继续执行Step 248的时候报错 49没有修改成功输入60退出 使用过程执行make报错一解决方式 继续make报错二解决方式 继续make执行生成文件helloworld报错三解决方式 执行make 完成参考链…

openeuler 22.03 lts sp4 使用 cri-o 和 静态 pod 的方式部署 k8s-v1.32.0 高可用集群

前情提要 整篇文章会非常的长…可以选择性阅读,另外,这篇文章是自己学习使用的,用于生产,还请三思和斟酌 静态 pod 的部署方式和二进制部署的方式是差不多的,区别在于 master 组件的管理方式是 kubectl 还是 systemctl有 kubeadm 工具,为什么还要用静态 pod 的方式部署?…

渗透测试之WAF规则触发绕过规则之规则库绕过方式

目录 Waf触发规则的绕过 特殊字符替换空格 实例 特殊字符拼接绕过waf Mysql 内置得方法 注释包含关键字 实例 Waf触发规则的绕过 特殊字符替换空格 用一些特殊字符代替空格&#xff0c;比如在mysql中%0a是换行&#xff0c;可以代替空格 这个方法也可以部分绕过最新版本的…

C# dataGridView1获取选中行的名字

在视觉项目中编写的框架需要能够选择产品或复制产品等方便后续换型&#xff0c;视觉调试仅需调试相机图像、调试视觉相关参数、标定&#xff0c;再试跑调试优化参数。 C# dataGridView1 鼠标点击某一行能够计算出是那一行 使用CellMouseClick事件 首先&#xff0c;在Form的构造…