Numpy where 函数多个条件

2025-01-16 08:38:00
admin
原创
89
摘要:问题描述:我有一个名为的距离数组dists。我想选择dists在一定范围内的距离。 dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))] 然而,这只针对条件进行选择 (np.where(dists <= r + dr)) ...

问题描述:

我有一个名为的距离数组dists。我想选择dists在一定范围内的距离。

 dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))]

然而,这只针对条件进行选择

 (np.where(dists <= r + dr))

如果我使用临时变量按顺序执行命令,它就可以正常工作。为什么上述代码不起作用?我该如何让它工作?


解决方案 1:

在您的特定情况下,最好的方法就是将两个标准更改为一个标准:

dists[abs(dists - r - dr/2.) <= dr/2.]

它只创建一个布尔数组,并且在我看来更容易阅读,因为它说,*是在或之dist内?dr`r*(虽然我会重新定义r为你感兴趣区域的中心而不是开头,所以r = r + dr/2.`)但这并不能回答你的问题。


你的问题的答案:如果你只是想过滤掉不符合你的标准的元素,那么

你实际上并不需要:where`dists`

dists[(dists >= r) & (dists <= r+dr)]

因为&将给你一个元素and(括号是必要的)。

where或者,如果由于某种原因你确实想使用,你可以这样做:

 dists[(np.where((dists >= r) & (dists <= r + dr)))]

原因:

它不起作用的原因是因为它np.where返回的是索引列表,而不是布尔数组。您试图and在两个数字列表之间进行选择,当然它们没有您期望的True/False值。如果ab都是True值,则a and b返回b。因此,说类似的话[0,1,2] and [2,3,4]只会给您[2,3,4]。以下是它的实际效果:

In [230]: dists = np.arange(0,10,.5)
In [231]: r = 5
In [232]: dr = 1

In [233]: np.where(dists >= r)
Out[233]: (array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),)

In [234]: np.where(dists <= r+dr)
Out[234]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),)

In [235]: np.where(dists >= r) and np.where(dists <= r+dr)
Out[235]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),)

您希望比较的只是布尔数组,例如

In [236]: dists >= r
Out[236]: 
array([False, False, False, False, False, False, False, False, False,
       False,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True], dtype=bool)

In [237]: dists <= r + dr
Out[237]: 
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True, False, False, False, False, False,
       False, False], dtype=bool)

In [238]: (dists >= r) & (dists <= r + dr)
Out[238]: 
array([False, False, False, False, False, False, False, False, False,
       False,  True,  True,  True, False, False, False, False, False,
       False, False], dtype=bool)

现在您可以调用np.where组合的布尔数组:

In [239]: np.where((dists >= r) & (dists <= r + dr))
Out[239]: (array([10, 11, 12]),)

In [240]: dists[np.where((dists >= r) & (dists <= r + dr))]
Out[240]: array([ 5. ,  5.5,  6. ])

或者简单地使用花式索引将原始数组与布尔数组一起索引

In [241]: dists[(dists >= r) & (dists <= r + dr)]
Out[241]: array([ 5. ,  5.5,  6. ])

解决方案 2:

接受的答案很好地解释了这个问题。但是,应用多个条件的更 Numpythonic 方法是使用numpy 逻辑函数。在这种情况下,您可以使用np.logical_and

np.where(np.logical_and(np.greater_equal(dists,r),np.greater_equal(dists,r + dr)))

解决方案 3:

这里要指出一个有趣的事实:通常使用ORAND的方式在本例中也适用,但需要做一点小改动。不要使用“and”和“or”,而是使用Ampersand(&)管道运算符 (|),这样就可以了。

当我们使用'and'时:

ar = np.array([3,4,5,14,2,4,3,7])
np.where((ar>3) and (ar<6), 'yo', ar)

Output:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

当我们使用Ampersand(&)时:

ar = np.array([3,4,5,14,2,4,3,7])
np.where((ar>3) & (ar<6), 'yo', ar)

Output:
array(['3', 'yo', 'yo', '14', '2', 'yo', '3', '7'], dtype='<U11')

当我们尝试在 pandas Dataframe 中应用多个过滤器时,情况也是如此。现在,这背后的原因与逻辑运算符和按位运算符有关,为了更好地理解这些内容,我建议阅读此答案或 stackoverflow 中的类似问答。

更新

有位用户问,为什么需要在括号内给出 (ar>3) 和 (ar<6)。好吧,事情是这样的。在我开始谈论这里发生的事情之前,需要了解 Python 中的运算符优先级。

与 BODMAS 类似,python 也优先考虑应该先执行的操作。括号内的项目先执行,然后按位运算符开始工作。下面我将展示使用和不使用“(”、“)”时会发生什么情况。

案例1:

np.where( ar>3 & ar<6, 'yo', ar)
np.where( np.array([3,4,5,14,2,4,3,7])>3 & np.array([3,4,5,14,2,4,3,7])<6, 'yo', ar)

由于这里没有括号,位运算符 ( &) 在这里会让人感到困惑,你到底在要求它对什么进行逻辑与运算,因为在运算符优先级表中,如果你看到,&的优先级高于<>运算符。以下是从最低优先级到最高优先级的表格。

在此处输入图片描述

它甚至没有执行“<与”>运算,而是被要求执行逻辑“与”运算。这就是它出现该错误的原因。

可以查看以下链接以了解有关运算符优先级的更多信息

现在来看案例 2:

如果您确实使用了支架,您就会清楚地看到会发生什么。

np.where( (ar>3) & (ar<6), 'yo', ar)
np.where( (array([False,  True,  True,  True, False,  True, False,  True])) & (array([ True,  True,  True, False,  True,  True,  True, False])), 'yo', ar)

两个 True 和 False 数组。您可以轻松地对它们执行逻辑与运算。结果如下:

np.where( array([False,  True,  True, False, False,  True, False, False]),  'yo', ar)

其余的您知道,np.where,对于给定的情况,如果为 True,则分配第一个值(即此处的“yo”),如果为 False,则分配另一个值(即此处保留原始值)。

就这样。希望我很好地解释了这个问题。

解决方案 4:

np.where()使用多个条件,只需执行以下操作:

np.where((condition 1) & (condition 2)) # for and
np.where((condition 1) | (condition 2)) # for or

我知道这重复了一些其他的答案,但是我在这里把这个简单的答案放在这里,让那些仍然想知道“为什么我会收到关于”的烦人的错误信息的人知道,The truth value of an array with more than one element is ambiguous他们对解决原始帖子的有些专业性质的非常冗长和复杂的答案感到困惑。

现在,至于为什么使用and而不是时 numpy 会中断&,我不会在这里尝试回答。它就是这样 :) 请参阅此处的其他答案以获取解释。在我看来,这似乎是他们应该修复的东西,而不是为了一致性而强制它。或者至少他们应该制作一个更好的错误消息。:)

解决方案 5:

这应该有效:

dists[((dists >= r) & (dists <= r+dr))]

解决方案 6:

我喜欢用它np.vectorize来完成这样的任务。考虑以下几点:

>>> # function which returns True when constraints are satisfied.
>>> func = lambda d: d >= r and d<= (r+dr) 
>>>
>>> # Apply constraints element-wise to the dists array.
>>> result = np.vectorize(func)(dists) 
>>>
>>> result = np.where(result) # Get output.

您还可以使用np.argwhere而不是np.where来清除输出。

解决方案 7:

尝试:

import numpy as np
dist = np.array([1,2,3,4,5])
r = 2
dr = 3
np.where(np.logical_and(dist> r, dist<=r+dr))
# Output: (array([2, 3, 4]),)

您可以查看逻辑函数了解更多详细信息。

解决方案 8:

尝试:

np.intersect1d(np.where(dists >= r)[0],np.where(dists <= r + dr)[0])

解决方案 9:

我已经算出这个简单的例子

import numpy as np

ar = np.array([3,4,5,14,2,4,3,7])

print [X for X in list(ar) if (X >= 3 and X <= 6)]

>>> 
[3, 4, 5, 4, 3]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用