Python 在给定条件下,如何选择数组的元素?

Python 在给定条件下,如何选择数组的元素?,python,numpy,Python,Numpy,假设我有一个numpy数组x=[5,2,3,1,4,5],y=['f','o','o','b','a','r']。我想选择y中与x中大于1小于5的元素对应的元素 我试过了 x = array([5, 2, 3, 1, 4, 5]) y = array(['f','o','o','b','a','r']) output = y[x > 1 & x < 5] # desired output is ['o','o','a'] x=array([5,2,3,1,4,5]) y=数

假设我有一个numpy数组
x=[5,2,3,1,4,5]
y=['f','o','o','b','a','r']
。我想选择
y
中与
x
中大于1小于5的元素对应的元素

我试过了

x = array([5, 2, 3, 1, 4, 5])
y = array(['f','o','o','b','a','r'])
output = y[x > 1 & x < 5] # desired output is ['o','o','a']
x=array([5,2,3,1,4,5])
y=数组(['f'、'o'、'o'、'b'、'a'、'r']))
输出=y[x>1&x<5]#所需输出为['o','o','a']

但这不起作用。我将如何执行此操作?

如果添加括号,表达式将正常工作:

>>> y[(1 < x) & (x < 5)]
array(['o', 'o', 'a'], 
      dtype='|S1')
>>y[(1
IMO OP并不是真正想要,而是真正想要,因为他们正在比较逻辑值,如
True
False
——请参阅下面的文章以了解差异

>>> x = array([5, 2, 3, 1, 4, 5])
>>> y = array(['f','o','o','b','a','r'])
>>> output = y[np.logical_and(x > 1, x < 5)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')
按数字:

>>> %timeit (a < b) & (b < c)
The slowest run took 32.97 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.15 µs per loop

>>> %timeit np.logical_and(a < b, b < c)
The slowest run took 32.59 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.17 µs per loop

>>> %timeit np.all([a < b, b < c], 0)
The slowest run took 67.47 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.06 µs per loop
>>%timeit(a>>%timeit np.logical_和(a>>%timeit np.all([a

因此,使用
np.all()
速度较慢,但
&
逻辑和
基本相同。

为@J.F.塞巴斯蒂安和@Mark Mikofski的答案添加一个细节:
如果希望获得相应的索引(而不是数组的实际值),则可以使用以下代码:

为了满足多个(全部)条件:

select_indices = np.where( np.logical_and( x > 1, x < 5) )[0] #   1 < x <5
select_indices = np.where( np.logical_or( x < 1, x > 5 ) )[0] # x <1 or x >5
select_index=np.where(np.logical_和(x>1,x<5))[0]#1
实际上我会这样做:

L1是满足条件1的元素索引列表;(也许您可以使用
somelist.index(条件1)
np.where(条件1)
来获取L1。)

类似地,得到L2,满足条件2的元素列表

然后使用
intersect(L1,L2)
查找交点

如果要满足多个条件,还可以找到多个列表的交集


然后,您可以在任何其他数组中应用索引,例如x。

我喜欢使用
np.vectorize
来执行此类任务。考虑以下事项:

>>> # Arrays
>>> x = np.array([5, 2, 3, 1, 4, 5])
>>> y = np.array(['f','o','o','b','a','r'])

>>> # Function containing the constraints
>>> func = np.vectorize(lambda t: t>1 and t<5)

>>> # Call function on x
>>> y[func(x)]
>>> array(['o', 'o', 'a'], dtype='<U1')
>#数组
>>>x=np.数组([5,2,3,1,4,5])
>>>y=np.array(['f','o','o','b','a','r'])
>>>#包含约束的函数
>>>func=np.vectorize(lambda t:t>1和t>>#调用x上的函数
>>>y[func(x)]

>>>数组(['o','o','a'],dtype='对于二维数组,您可以执行此操作。使用条件创建二维掩码。根据数组,将条件掩码键入int或float,并将其与原始数组相乘

In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])

您需要注意如何谈论所评估的内容。例如,在
output=y[np.logical_和(x>1,x<5)]
中,对
x<5
进行评估(可能会创建一个巨大的数组),即使它是第二个参数,因为求值发生在函数之外。这样,
logical\u和
会传递两个已经求值的参数。这与
a和b
的通常情况不同,在这种情况下,如果
a
是truelike,则不会求值
b
。按位\u和()和逻辑_和()用于布尔数组我一直在寻找“或”的替代方案,这个答复给了我一些急需的缓解!非常感谢。(np.logical_或),显然…那很好=1@JennyYueJin:由于优先级而发生。(按位)
&
的优先级高于
,后者的优先级依次高于(逻辑)
x>1和x<5
首先计算不等式,然后计算逻辑合取;
x>1和x<5
计算
1和(中的值)
x
,然后是不等式。
(x>1)和(x<5)
强制首先计算不等式,因此所有操作都按预定顺序进行,结果都定义良好。@ru111它也适用于Python 3.6(没有理由停止工作)。我得到“ValueError:包含多个元素的数组的真值不明确。请使用a.any()或a.all()”@ru111您应该编写
(0
(如答案所示)而不是
0
,它在任何Python版本上都不适用于numpy数组。请注意,numpy.where不仅返回索引数组,而是返回包含数组的元组(condition.nonzero()的输出)-在本例中为
(所需的索引数组)
,因此您需要
选择_indexes=np。其中(…)[0]
来获得您想要的结果。这不是在NumPy中进行索引的好方法(它会非常慢)。
In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])