从Numpy数组和浮点数的元素中获得最小值

时间:2015-01-12 14:14:33

标签: python arrays numpy min

问题:我想将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)

但是,我担心这不是最有效的解决方案。是否有更优雅/有效的方法来实现这一目标?

5 个答案:

答案 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关键字,其他版本则不接受。

在我的时间内,

clipminimum之上有一个适度的优势。但是我建议哪一个看起来最清楚。