【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_position
    min_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_position
    min_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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

毕业设计--具有车流量检测功能的智能交通灯设计

摘要&#xff1a; 随着21世纪机动车保有量的持续增加&#xff0c;城市交通拥堵已成为一个日益严重的问题。传统的固定绿灯时长方案导致了大量的时间浪费和交通拥堵。为解决这一问题&#xff0c;本文设计了一款智能交通灯系统&#xff0c;利用车流量检测功能和先进的算法实现了…

课题推荐:基于matlab,适用于自适应粒子滤波的应用

自适应粒子滤波&#xff08;Adaptive Particle Filter, APF&#xff09;是一种用于状态估计的有效方法&#xff0c;特别适用于非线性和非高斯系统。 文章目录 应用场景MATLAB 代码示例代码说明结果扩展说明 以下是一个基于自适应粒子滤波的简单应用示例&#xff0c;模拟一个一维…

Redis(5,jedis和spring)

在前面的学习中&#xff0c;只是学习了各种redis的操作&#xff0c;都是在redis命令行客户端操作的&#xff0c;手动执行的&#xff0c;更多的时候就是使用redis的api&#xff08;&#xff09;&#xff0c;进一步操作redis程序。 在java中实现的redis客户端有很多&#xff0c;…

基于聚类与相关性分析对马来西亚房价数据进行分析

碎碎念&#xff1a;由于最近太忙了&#xff0c;更新的比较慢&#xff0c;提前祝大家新春快乐&#xff0c;万事如意&#xff01;本数据集的下载地址&#xff0c;读者可以自行下载。 1.项目背景 本项目旨在对马来西亚房地产市场进行初步的数据分析&#xff0c;探索各州的房产市…

(2025 年最新)MacOS Redis Desktop Manager中文版下载,附详细图文

MacOS Redis Desktop Manager中文版下载 大家好&#xff0c;今天给大家带来一款非常实用的 Redis 可视化工具——Redis Desktop Manager&#xff08;简称 RDM&#xff09;。相信很多开发者都用过 Redis 数据库&#xff0c;但如果你想要更高效、更方便地管理 Redis 数据&#x…

智慧园区管理系统为企业提供高效运作与风险控制的智能化解决方案

内容概要 快鲸智慧园区管理系统&#xff0c;作为一款备受欢迎的智能化管理解决方案&#xff0c;致力于为企业提供高效的运作效率与风险控制优化。具体来说&#xff0c;这套系统非常适用于工业园、产业园、物流园、写字楼及公寓等多种园区和商办场所。它通过数字化与智能化的手…

C++中常用的排序方法之——冒泡排序

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C中常用的排序方法之——冒泡排序的…

基础项目实战——3D赛车(c++)

目录 前言一、渲染引擎二、关闭事件三、梯形绘制四、轨道绘制五、边缘绘制六、草坪绘制七、前后移动八、左右移动​九、曲线轨道​十、课山坡轨道​十一、循环轨道​十二、背景展示​十三、引入速度​十四、物品绘制​十五、课数字路障​十六、分数展示​十七、重新生成​十八、…

深度学习指标可视化案例

TensorBoard 代码案例&#xff1a;from torch.utils.tensorboard import SummaryWriter import torch import torchvision from torchvision import datasets, transforms# 设置TensorBoard日志路径 writer SummaryWriter(runs/mnist)# 加载数据集 transform transforms.Comp…

AI时序预测: iTransformer算法代码深度解析

在之前的文章中&#xff0c;我对iTransformer的Paper进行了详细解析&#xff0c;具体文章如下&#xff1a; 文章链接&#xff1a;深度解析iTransformer&#xff1a;维度倒置与高效注意力机制的结合 今天&#xff0c;我将对iTransformer代码进行解析。回顾Paper&#xff0c;我…

Java内存模型 volatile 线程安全

目录 Java内存模型可见性例子和volatilevolatile如何保证可见性原子性与单例模式i非原子性 线程安全 Java内存模型 参考学习: Java Memory Model外文文档 CPU与内存&#xff0c;可参考&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145303267 Java线程与内…

【FreeRTOS 教程 三】协程状态、优先级、实现及调度

目录 一、协程介绍&#xff1a; &#xff08;1&#xff09;协程的特点&#xff1a; &#xff08;2&#xff09;协程的优势&#xff1a; 二、协程状态&#xff1a; &#xff08;1&#xff09;协程状态说明&#xff1a; &#xff08;2&#xff09;协程状态图示&#xff1a;…

堆的存储(了解)

由于堆是⼀个完全⼆叉树&#xff0c;因此可以⽤⼀个数组来存储。&#xff08;如果不清楚大家可以回顾⼆叉树的存储&#xff08;上&#xff09;c文章里的顺序存储&#xff09; 结点下标为 i &#xff1a; 如果⽗存在&#xff0c;⽗下标为 i/2 &#xff1b; 如果左孩⼦存在&…

谭浩强C语言程序设计(3) 7章

1、递归实现N的阶乘 c复制 #include <cstdio> // 包含标准输入输出库// 计算n的阶乘 int total 0; // 定义全局变量total用于存储阶乘结果// 递归函数计算阶乘 int fac(int a){// 如果输入的数小于0&#xff0c;输出错误信息if (a < 0){printf("%d < 0,err…

WPF基础 | WPF 常用控件实战:Button、TextBox 等的基础应用

WPF基础 | WPF 常用控件实战&#xff1a;Button、TextBox 等的基础应用 一、前言二、Button 控件基础2.1 Button 的基本定义与显示2.2 按钮样式设置2.3 按钮大小与布局 三、Button 的交互功能3.1 点击事件处理3.2 鼠标悬停与离开效果3.3 按钮禁用与启用 四、TextBox 控件基础4.…

MATLAB的数据类型和各类数据类型转化示例

一、MATLAB的数据类型 在MATLAB中 &#xff0c;数据类型是非常重要的概念&#xff0c;因为它们决定了如何存储和操作数据。MATLAB支持数值型、字符型、字符串型、逻辑型、结构体、单元数组、数组和矩阵等多种数据类型。MATLAB 是一种动态类型语言&#xff0c;这意味着变量的数…

模型I/O

文章目录 什么是模型I/O模型I/O功能之输出解析器输出解析器的功能输出解析器的使用Pydantic JSON输出解析器结构化输出解析器 什么是模型I/O 模型I/O在所有LLM应用中&#xff0c;核心元素无疑都是模型本身。与模型进行有效的交互是实现高效、灵活和可扩展应用的关键。LangChain…

docker安装Redis:docker离线安装Redis、docker在线安装Redis、Redis镜像下载、Redis配置、Redis命令

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull redis:7.4.0 2、离线包下载 两种方式&#xff1a; 方式一&#xff1a; -&#xff09;在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -&#xff09;导出 # 导出镜像…

QT串口通信,实现单个温湿度传感器数据的采集

1、硬件设备 RS485中继器(一进二出),usb转485模块、电源等等 => 累计115元左右。 2、核心代码 #include "MainWindow.h" #include "ui_MainWindow.h"MainWindow::

android主题设置为..DarkActionBar.Bridge时自定义DatePicker选中日期颜色

安卓自定义DatePicker选中日期颜色 背景&#xff1a;解决方案&#xff1a;方案一&#xff1a;方案二&#xff1a;实践效果&#xff1a; 背景&#xff1a; 最近在尝试用原生安卓实现仿element-ui表单校验功能&#xff0c;其中的的选择日期涉及到安卓DatePicker组件的使用&#…