np.where多条件筛选_np.where性能优化
â�±ï¸� 刚å¦Pythonçš„å°�白是ä¸�æ˜¯æ€»è¢«ä¸€å †if-else
�晕?尤其�对数组数�时,写循�慢到怀疑人生…别慌�​​NumPy的np.where
​​ 就是专治这ç§�痛点的ç¥�器ï¼�ä»Šå¤©æ‰‹æŠŠæ‰‹æ•™ä½ ç”¨å®ƒçš„å¤šæ�¡ä»¶æŠ€å·§ï¼Œâ€‹â€‹æ��速50å€�​​还能少写80%代ç �ï¼�
ğŸ”� 什么是np.where?简å�•到å“的比喻ï¼�
æƒ³è±¡ä½ æœ‰ä¸€ç�苹æ�œğŸ��和一ç�橘å�ğŸ�Šï¼Œè€�æ�¿è¯´ï¼šâ€œå��æ�œä¸¢æ�‰ï¼Œå¥½æ�œæŒ‰ç§�类分开放ï¼�â€� —— ​​np.where
就是自动化分拣机​​�
- ​​��件模�​​:
np.where(æ°´æ�œ==好æ�œ, ä¿�å˜, 丢æ�‰)
- ​​多�件模�​​:
np.where((æ°´æ�œ==苹æ�œ)&(好æ�œ), 放红ç�, np.where(...))
看,​​�件组�直�用&
(�)�|
(或)​​,�用写循�就能批��作�
💡 ​​个人踩�心得​​:别�用and
/or
�必须用​​&
�|
​​,å�¦åˆ™æŠ¥é”™åˆ°ä½ å“ï¼�括å�·ä¹Ÿå¾—包严å®�,比如(æ�¡ä»¶A) & (æ�¡ä»¶B)
🚀 多æ�¡ä»¶ç›é€‰å®�战:3ç§�高频场景
场景1:å¦ç”Ÿæˆ�绩分级(90分以上A,80-89分B...)
python�行�制import numpy as np scores = np.array([88, 92, 75, 60, 45, 70]) # 嵌套np.where��多级分类 grade = np.where(scores >= 90, "A", np.where(scores >= 80, "B", np.where(scores >= 70, "C", "D"))) print(grade) # 输出: ['B' 'A' 'C' 'D' 'D' 'C']
​​关键点​​:​​ä»�ä¸¥æ ¼æ�¡ä»¶å¼€å§‹åµŒå¥—​​(比如先判≥90,å†�判≥80)
场景2:电商库å˜è¿‡æ»¤ï¼ˆä»·æ ¼>100且库å˜<10的商å“�æ‰“æ ‡ï¼‰
pythonè¿�行å¤�制prices = np.array([150, 80, 200, 99]) stocks = np.array([5, 20, 8, 15]) # &组å�ˆå�Œæ�¡ä»¶ï¼Œä¸€æ¬¡æ€§è¾“å‡ºæ ‡ç¾ tag = np.where((prices > 100) & (stocks < 10), "紧急补货", "æ£å¸¸") print(tag) # 输出: ['紧急补货' 'æ£å¸¸' '紧急补货' 'æ£å¸¸']
​​é�¿å�‘​​:​​æ�¡ä»¶æ•°ç»„形状必须一致​​ï¼�å�¦åˆ™å¹¿æ’机制失效
场景3:图åƒ�阈值分割(红色通é�“>200且è“�色<50çš„åƒ�ç´ å�˜ç™½ï¼‰
pythonè¿�行å¤�制# 模拟RGB图åƒ� (3x3åƒ�ç´ ) image = np.array([[[255, 30, 40], [200, 100, 50]], [[30, 220, 10], [10, 50, 250]]]) # 拆解RGB通é�“ red = image[:, :, 0] blue = image[:, :, 2] # 多æ�¡ä»¶å®šä½�åƒ�ç´ white_mask = np.where((red > 200) & (blue < 50), 255, image)
👉 ​​输出效æ�œâ€‹â€‹ï¼šä»…满足æ�¡ä»¶çš„åƒ�ç´ å�˜æˆ�纯白,其余ä¿�ç•™å�Ÿå›¾
⚡ 性能优化秘�:�速50��是梦�
对比�验:10万数��处�
python�行�制import time data = np.random.rand(100000) # 10万个�机数 # Python循�版 start = time.time() result_loop = [x*2 if x>0.5 else x/2 for x in data] print(f"循�耗时: {time.time()-start:.4f}秒") # np.where版 start = time.time() result_np = np.where(data > 0.5, data*2, data/2) print(f"np.where耗时: {time.time()-start:.4f}秒")
​​结�惊呆​​:
- 循�耗时:​​0.39秒​​
- np.where耗时:​​0.008秒​​ 👉 ​​速度��48��​​
✅ 3个优化�则(附��指�)
-
​​����计算�件​​
� 错误写法:np.where(data>0.5, data*2, data/2)
+ å��ç»å�ˆç®—data>0.5
✅ æ£ç¡®å�šæ³•ï¼šâ€‹â€‹é¢„å˜æ�¡ä»¶å�˜é‡�​​ →condition = data>0.5
,å��ç»å¤�用 -
​​高维数�用索引代替嵌套​​
python�行�制
# �效嵌套 result = np.where(cond1, x, np.where(cond2, y, z)) # 高效方案:用索引直�定� result = choices[np.where(conditions)] # choices=[x,y,z]
-
​​别在np.where里调��函数​​�
⚠� 例如:np.where(x>0, heavy_func(x), 0)
问题:​​heavy_func会全�执行​​,浪费资��
改用:​​先计算�赋值​​ →y = heavy_func(x); np.where(x>0, y, 0)
ğŸ’� 独家进阶:多æ�¡ä»¶+å¹¿æ’æœºåˆ¶ç»“å�ˆ
当æ�¡ä»¶å€¼å’Œè¾“出值形状ä¸�å�Œæ—¶ï¼Œâ€‹â€‹å¹¿æ’机制自动对é½�​​ï¼�
pythonè¿�行å¤�制# 二维æ�¡ä»¶ + 一维值 cond_2d = np.array([[True, False], [False, True]]) # 自动广æ’:Trueä½�ç½®å�–[10,20]ä¸å¯¹åº”索引的值 result = np.where(cond_2d, [10, 20], 0) print(result) # 输出:[[10, 0], [0, 20]]
​​应用场景​​:比如对矩阵ä¸�å�Œåˆ—用ä¸�å�Œé˜ˆå€¼å¤„ç�†ï¼Œâ€‹â€‹ä¸€è¡Œä»£ç �æ��定​​ï¼�
🌟 ​​终�建议​​:
- ​​简��件​​ → 直�用
&
�|
组� - ​​超多分支​​ → 改用
np.select([cond1,cond2], [choice1,choice2], default)
- ​​性能瓶颈​​ → 和
numba
ç¼–è¯‘åŠ é€Ÿæ�é…�使用,轻æ�¾å¤„ç�†â€‹â€‹å�ƒä¸‡çº§æ•°æ�®â€‹â€‹ï¼�