问题:我想将Numpy数组的每个元素与float进行比较,返回一个值较小的数组。例如,使用输入:
import numpy as np
input_a = 3
input_b = np.array([1,2,3,4,5])
输出应为
output = np.array([1,2,3,3,3])
我目前的解决方案是使用只有常量的新np.array,然后使用np.minimum()。
c = np.copy(input_b)
c.fill(input_a)
output = np.minimum(input_b, c)
但是,我担心这不是最有效的解决方案。是否有更优雅/有效的方法来实现这一目标?
答案 0 :(得分:2)
您最好的选择是使用logical indexing.
import numpy as np
input_a = 3
input_b = np.array([1,2,3,4,5])
input_b[input_b > input_a] = input_a
print(input_b)
# [1 2 3 3 3]
input_b > input_a
将返回一个True或False值的掩码数组,在这种情况下,如果input_b
中的对应元素大于input_a
,则该元素将为True。然后,您可以使用它来索引input_b
并仅修改这些值。
请注意,使用逻辑索引比使用numpy.where
对此特定数组更快,但我无法准确地告诉您原因。
setup = 'from __main__ import np, input_a, input_b'
print(timeit.timeit('input_b[input_b > input_a] = input_a', setup=setup))
# 2.2448947575996456
print(timeit.timeit('np.where(input_b < input_a, input_b, input_a)', setup=setup))
# 5.35540746395358
答案 1 :(得分:1)
我认为np.minimum
适用于此操作:
>>> np.minimum(input_b, 3)
array([1, 2, 3, 3, 3])
如果您想直接修改input_b
,请使用out
关键字参数以成对的最小值填充input_b
。
>>> np.minimum(input_b, 3, out=input_b)
>>> input_b
array([1, 2, 3, 3, 3])
这比使用布尔索引然后分配值更快:
>>> %timeit input_b[input_b > input_a] = input_a
100000 loops, best of 3: 4.16 µs per loop
>>> %timeit np.minimum(input_b, 3, out=input_b)
100000 loops, best of 3: 2.53 µs per loop
答案 2 :(得分:0)
这样做的一个方法就是使用numpy.where
:
>>> np.where(input_b < input_a, input_b, input_a)
array([ 1., 2., 3., 3., 3.])
这里我们传递numpy.where
三个参数,其中第一个是input_b < input_a
的布尔数组。每当第一个参数中的值为True
时,我们从第二个参数(input_b
)获取相应索引处的值。否则,我们取值为input_a
。
修改:事实上,正如@ Kasra的回答所示,您可以直接传递input_a
,而无需将其转换为np.array
。
答案 3 :(得分:0)
您可以使用numpy.where
:
>>> np.where(input_b < input_a, input_b, input_a)
array([1, 2, 3, 3, 3])
答案 4 :(得分:0)
有一个内置功能:clip
output = input_b.clip(max=input_a)
或者如果您想要设置input_b
本身
np.clip(input_b, None, out=input_b)
此处它与minimum
相同,但它也可以在同一个调用中执行maximum
。某些版本接受max
关键字,其他版本则不接受。
clip
在minimum
之上有一个适度的优势。但是我建议哪一个看起来最清楚。