【NumPy】一文详细介绍 np.where()

【NumPy】一文详细介绍 np.where()
在这里插入图片描述

🌈 欢迎进入我的个人主页,我是高斯小哥!👈

🎓 博主档案: 广东某985本硕,SCI顶刊一作,深耕深度学习多年,熟练掌握PyTorch框架。

🔧 技术专长: 擅长处理各类深度学习任务,包括但不限于图像分类、图像重构(去雾\去模糊\修复)、目标检测、图像分割、人脸识别、多标签分类、重识别(行人\车辆)、无监督域适应、主动学习、机器翻译、文本分类、命名实体识别、知识图谱、实体对齐、时间序列预测等。业余时间,成功助力数百位用户解决技术难题,深受用户好评

📝 博客风采: 我坚信知识分享的力量,因此在博客中倾注心血,分享深度学习、PyTorch、Python的优质内容。本年已发表原创文章300+,代码分享次数突破2w+,为广大读者提供了丰富的学习资源和实用解决方案。

💡 服务项目: 提供科研入门辅导(主要是代码方面)、知识答疑、定制化需求解决等服务,助力你的深度学习之旅(有需要可私信联系)。

🌟 期待与你共赴深度学习之旅,书写精彩篇章!感谢关注与支持!🚀


🔍一、NumPy简介与np.where()初探

  NumPy(Numerical Python的简称)是Python中用于进行数值计算的扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。NumPy的核心功能是提供n维数组对象,其基础数据类型为ndarray,该类型是一个快速的、灵活的大数组容器,可以用于存储和处理大型数据集。

  在NumPy中,np.where()是一个强大的函数,它根据条件对数组元素进行选择或替换。其基本语法为:np.where(condition[, x, y])。其中,condition是条件表达式,xy是可选参数,表示满足条件和不满足条件时的返回值。

📚二、np.where()的基本用法

  • 下面通过一个简单的例子来演示np.where()的基本用法:

    import numpy as np
    
    # 创建一个数组
    arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    # 定义一个条件:找出数组中大于5的元素
    condition = arr > 5
    
    # 使用np.where()根据条件选择元素
    result = np.where(condition, '大于5', '小于等于5')
    
    print(result)  # 输出:['小于等于5' '小于等于5' '小于等于5' '小于等于5' '小于等于5' '大于5' '大于5' '大于5' '大于5']
    

在上面的例子中,我们首先创建了一个数组arr,然后定义了一个条件condition,即找出数组中大于5的元素。接着,我们使用np.where()函数,将满足条件的元素替换为字符串’大于5’,不满足条件的元素替换为’小于等于5’。最后,打印出结果数组result

💡三、np.where()的高级用法

  除了基本用法外,np.where()还可以结合其他NumPy函数进行更复杂的操作。下面介绍一些高级用法:

  1. 同时处理多个条件

    可以通过逻辑运算符(如&|)组合多个条件,并使用np.where()处理这些条件。

    import numpy as np
    
    # 创建两个数组
    arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    arr2 = np.array([9, 8, 7, 6, 5, 4, 3, 2, 1])
    
    # 定义多个条件
    condition1 = arr1 > 5
    condition2 = arr2 < 4
    
    # 使用np.where()处理多个条件
    result = np.where((condition1 & condition2), '两者都满足', '至少有一个不满足')
    
    print(result)  # 输出:['至少有一个不满足' '至少有一个不满足' '至少有一个不满足' '两者都满足' '两者都满足' '两者都满足' '两者都满足' '两者都满足' '两者都满足']
    
  2. 返回满足条件的元素索引

    默认情况下,np.where()返回满足条件的元素值。如果想要返回满足条件的元素的索引,可直接对条件表达式使用np.where()

    import numpy as np
    
    # 创建一个数组
    arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    # 定义一个条件:找出数组中大于5的元素
    condition1 = arr > 5
    
    # 获取满足条件的元素索引
    indices = np.where(condition1)
    
    print(indices)  # 输出:(array([5, 6, 7, 8]),)
    
  3. 在数组中根据条件替换值

    np.where()还可以直接在原数组上进行值替换。

    import numpy as np
    
    # 创建一个数组
    arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    # 定义一个条件:找出数组中大于5的元素
    condition1 = arr > 5
    
    # 根据条件在数组中替换值
    arr[np.where(condition1)] = -1
    
    print(arr)  # 输出:[ 1  2  3  4  5 -1 -1 -1 -1]
    

🌈四、np.where()的应用场景

  np.where()函数在数据处理和分析中有着非常广泛的应用。它可以帮助我们快速筛选出满足特定条件的元素,或者根据条件对元素进行替换。这在数据分析、机器学习、图像处理等领域都非常有用。

  例如,在机器学习中,我们可能需要根据某个阈值将连续变量转换为二分类变量;在图像处理中,我们可以根据像素值的大小来筛选特定的区域或对象。

💼五、与其他函数的结合使用

  np.where()函数经常与其他NumPy函数结合使用,以实现更复杂的数据操作和分析。以下是一些常见的结合使用方式:

  1. 与逻辑函数结合

    使用np.logical_andnp.logical_or等逻辑函数与np.where()结合,可以实现更复杂的条件判断。

    import numpy as np
    
    # 创建两个数组
    arr1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    arr2 = np.array([9, 8, 7, 6, 5, 4, 3, 2, 1])
    
    # 使用逻辑函数组合条件
    condition_combined = np.logical_and(arr1 > 3, arr2 < 7)
    result = np.where(condition_combined, '组合条件满足', '组合条件不满足')
    
    print(result)  # 输出:['组合条件不满足' '组合条件不满足' '组合条件不满足' '组合条件满足' '组合条件满足' '组合条件满足' '组合条件不满足' '组合条件不满足' '组合条件不满足']
    
  2. 与统计函数结合

    结合使用np.meannp.sum等统计函数,可以在满足条件的子集上进行统计计算。

    import numpy as np
    
    # 创建一个数组
    arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    # 定义一个条件:找出数组中大于5的元素
    condition1 = arr > 5
    
    # 计算满足条件的元素的平均值
    mean_value = np.mean(arr[condition1])
    print(mean_value) 
    
  3. 与排序函数结合

    使用np.argsortnp.sort对数组进行排序后,结合np.where()可以选择排序后的特定元素。

    import numpy as np
    
    # 创建一个数组
    arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    # 对数组进行排序,并获取排序后的索引
    sorted_indices = np.argsort(arr)
    
    # 选择排序后前三个元素的索引
    top_three_indices = np.where(sorted_indices < 3)[0]
    
    print(top_three_indices)  # 输出:数组中的最小三个元素的索引
    

🚀六、性能优化与注意事项

  在使用np.where()时,需要注意其性能影响,尤其是在处理大型数据集时。为了提高性能,可以考虑以下几点:

  • 避免不必要的条件判断:尽量使用高效的逻辑表达式,避免在循环或条件语句中重复使用np.where()
  • 利用向量化操作:NumPy的强大之处在于其向量化操作,尽量利用向量化操作代替循环,以提高性能。
  • 数据类型匹配:确保传递给np.where()的数据类型匹配,以避免不必要的数据类型转换开销。

此外,还需要注意np.where()返回的是元组或数组,根据实际需求进行处理。如果需要返回单个数组或值,可能需要对返回结果进行进一步的操作或转换。

📚七、总结与展望

  np.where()是NumPy中一个非常实用的函数,它可以根据条件对数组元素进行选择或替换。通过深入理解和灵活应用np.where(),我们可以更加高效地进行数据处理和分析。

  在未来,随着数据科学和机器学习的不断发展,对数组操作的需求将会更加复杂和多样化。因此,我们需要不断学习和探索新的NumPy函数和技巧,以应对各种挑战和需求。

  希望本文能够帮助你深入理解np.where()的用法和技巧,并在实际应用中取得更好的效果。如果你对NumPy的其他函数或主题感兴趣,欢迎继续关注和探索!🔍📚🚀

🌸结语

通过本文的介绍,相信你已经对NumPy中的np.where()函数有了更深入的了解。掌握这个强大的工具,将让你在数据处理和分析的道路上更加游刃有余。感谢你的阅读,期待你在未来的学习和实践中取得更多进步!🌟💪

import datetime import numpy as np import oracledb import pandas as pd import matplotlib.pyplot as plt from pptx import Presentation from pptx.util import Inches import os import matplotlib.colors from matplotlib.patches import Patch import time import logging import test import concurrent.futures # 获取当前时间 now = datetime.datetime.now() # 将时间转换为字符串,格式为YYYY-MM-DD_HH-MM-SS timestamp = now.strftime("%Y-%m-%d") logger = logging.getLogger() logger.setLevel(logging.INFO) format = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') logFile = f'{timestamp}-log.txt' fh = logging.FileHandler(logFile, mode='a', encoding='utf-8') fh.setLevel(logging.INFO) fh.setFormatter(format) logger.addHandler(fh) start_time1 = time.time() # 数据库连接信息 dsn = ( "(DESCRIPTION=" "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.164.60)(PORT=1521)))" "(CONNECT_DATA=(SERVICE_NAME=YMSDB01)))" ) username = 'acme' password = 'acme' oracledb.init_oracle_client(lib_dir=r"C:\Users\Q06412\Downloads\instantclient-basic-windows.x64-21.17.0.0.0dbru\instantclient_21_17") # 创建连接 connection = oracledb.connect(user=username, password=password, dsn=dsn) try: # 创建一个游标 cursor = connection.cursor() logging.info("SQL查询5个状态为0的lot任务---开始") # SQL 查询语句 sql_query = """ SELECT DISTINCT DRB_ID FROM ( SELECT DISTINCT DRB_ID,LOT_ID,ROW_NUMBER () OVER (ORDER BY CREATE_TIME ASC) AS RN FROM DRB_INFO_CONFIG dic WHERE STATUS=0 ) DRB_CNT WHERE RN <=5 """ # 执行查询 cursor.execute(sql_query) # 获取所有结果 lotresults = cursor.fetchall() logging.info("SQL查询5个状态为0的lot任务---结束") # print(len(results)) ==5 遍历每个drblot for i in range(0, len(lotresults)): # 5个lot查出来立马修改status=2,表示正在进程中 sql_query = """ update DRB_INFO_CONFIG set STATUS = :1 where DRB_ID = :2 """ cursor.execute(sql_query, (2, lotresults[i][0])) connection.commit() except Exception as e: logging.info(e) finally: # 关闭游标和连接 cursor.close() connection.close() def execute_query(sql_query): # 每个线程独立创建连接(关键!避免线程安全问题) # 创建连接 connection = oracledb.connect(user=username, password=password, dsn=dsn) cursor = connection.cursor() try: cursor.execute(sql_query) results = cursor.fetchall() return results # 返回结果供主线程收集 except Exception as ee: logging.info(ee) finally: connection.close() # 确保关闭连接 with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: # 控制并发数 # 提交所有查询任务 future_to_query = { executor.submit(execute_query, test.sql_query): test for test in lotresults } # 收集结果(按完成顺序) results = [] for future in concurrent.futures.as_completed(future_to_query): test = future_to_query[future] try: result = future.result() results.append(result) # 存储结果 except Exception as e: print(f"Query {test.sql_query} failed: {e}") end_time1 = time.time() run_time = end_time1 - start_time1 logging.info("代码运行时间为: %s 秒", run_time)
最新发布
03-22
<think>嗯,用户给了一段Python代码,还让我介绍一下里面的各个导入的库和整体功能。首先,我需要仔细看一下代码结构,了解各个部分的作用。 首先,用户导入了很多库,比如datetime、numpy、oracledb、pandas、matplotlib等等。这些都是Python中常用的数据处理、数据库连接、可视化相关的库。然后,代码里还涉及到生成PPT、日志记录、多线程处理,看起来像是一个自动化处理数据的脚本,可能用于从数据库提取数据,生成报告之类的。 接下来,代码里获取当前时间,设置日志记录,连接到Oracle数据库。这里用了oracledb库,可能需要客户端库,所以用户指定了init_oracle_client的路径。然后执行SQL查询,获取5个状态为0的DRB_ID,之后更新这些记录的状态为2,表示正在处理。这部分可能涉及到任务队列的处理,防止重复处理同一个任务。 然后,定义了一个execute_query函数,用来执行SQL查询,每个线程独立创建连接,避免线程安全问题。这里用了concurrent.futures的ThreadPoolExecutor来并发执行查询,最多5个线程同时进行。提交任务后,收集结果,最后计算整个代码的运行时间,并记录日志。 不过,用户的问题是要介绍这些导入的库,以及整个代码的功能。可能用户是想了解这段代码的作用,或者学习这些库的用途。需要注意代码中可能存在的问题,比如多线程处理数据库连接是否正确,是否有资源泄露,或者异常处理是否完善。 比如,在更新状态为2的时候,是在for循环里执行cursor.execute,但这里可能有问题,因为循环中的每个lotresults[i][0]是否都被正确处理?另外,多线程部分,每个线程都创建自己的连接,这是正确的做法,因为数据库连接不是线程安全的。但需要确认是否正确关闭了连接,在execute_query函数里用了connection.close(),应该没问题。 另外,用户可能没有注意到,在并发查询部分,test.sql_query可能有问题,因为test是从lotresults中取的,而lotresults的元素是之前查询得到的DRB_ID。这里的test变量可能并不是一个包含sql_query属性的对象,这部分代码可能有错误。因为lotresults的每个元素是从SELECT DISTINCT DRB_ID获取的,所以lotresults[i][0]是DRB_ID的值,而后面在提交任务时,循环的是test in lotresults,而test是元组,可能没有sql_query属性。这可能是个bug,需要指出。 此外,日志记录的部分是否正确配置,比如fh的处理程序是否添加正确,是否重复添加了handler导致日志重复输出。还有,在多线程环境下,日志记录是否线程安全,但logging模块本身是线程安全的,所以应该没问题。 总结下来,这段代码的主要功能是从Oracle数据库获取待处理的任务,更新状态为处理中,然后并发执行多个查询,收集结果,记录运行时间。可能用于批量处理任务,生成报告或进行数据分析。但代码中存在可能的错误,比如test.sql_query的使用,需要用户检查这部分是否正确。</think>我将分步骤解析这段代码的功能和结构,并着重说明主要模块的作用: 一、模块导入部分(技术选型分析) 1. 数据处理核心库 - `numpy`:用于科学计算,处理多维数组 $shape = (m,n)$ - `pandas`:数据清洗/分析的利器,DataFrame 结构 $df = pd.DataFrame(data)$ - `matplotlib`:数据可视化核心库,生成 $y = f(x)$ 等图表 2. 数据库交互 - `oracledb`:Oracle 官方 Python 驱动,支持最新数据库特性 - 连接池配置:`init_oracle_client` 指定客户端库路径 3. 自动化办公 - `pptx`:实现 PPT 自动生成,通过 `Inches` 控制元素布局 - `os`:文件路径操作,保障跨平台兼容性 4. 辅助工具 - `datetime` + `time`:时间戳生成 $t = \frac{1}{2}gt^2$ 和性能监控 - `logging`:标准化日志记录,格式为 `%(asctime)s %(filename)s...` - `concurrent.futures`:实现多线程并发查询 二、核心执行流程(架构图示意) $$ \begin{aligned} 1.\ & \text{初始化日志系统} \\ 2.\ & \text{建立数据库连接} \\ 3.\ & \text{查询待处理任务(状态0的DRB_ID)} \\ 4.\ & \text{批量更新任务状态为处理中(状态2)} \\ 5.\ & \text{使用线程池并发执行查询} \\ 6.\ & \text{结果收集与性能分析} \end{aligned} $$ 三、关键技术亮点 1. 多线程优化 - 采用 `ThreadPoolExecutor` 实现并发查询 - 每个线程独立创建连接(解决线程安全问题) - 最大并发数控制为5(`max_workers=5`) 2. 数据库操作安全 ```python try: cursor.execute(sql) connection.commit() # 显式提交事务 except Exception as e: logger.error(e) # 异常捕获 finally: connection.close() # 资源释放保障 ``` 四、潜在优化建议 1. 连接池管理:建议使用 `SessionPool` 替代频繁创建连接 2. 异常处理增强:增加重试机制应对网络波动 3. 配置分离:将数据库连接参数提取到配置文件中 4. SQL 注入防护:对 `lotresults[i][0]` 进行参数化校验 五、性能监控设计 - 使用时间差计算执行时长: $$ \Delta t = t_{end} - t_{start} $$ - 日志记录运行时长:`logging.info("代码运行时间为:%s 秒", run_time)` 该代码实现了从 Oracle 数据库获取任务、并行处理数据到生成分析报告的完整自动化流程,适用于制造业数据分析、质量监控等场景。建议重点检查 `test.sql_query` 的引用是否正确(当前代码存在未定义风险)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高斯小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值