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

Getting the minimum from elements of a Numpy array and a float

问题:我想将 Numpy 数组的每个元素与浮点数进行比较,返回具有较小值的数组。例如,使用输入:

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)

但是,恐怕这不是最有效的解决方案。有没有更优雅/更有效的方法来实现这一目标?

我认为 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

你最好的选择是使用 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 将 return 为 True 或 False 值的掩码数组,在这种情况下,如果 input_b 中的对应元素大于 input_a。然后您可以使用它来索引 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

一个简单的方法是使用 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.

您可以使用 numpy.where :

>>> np.where(input_b < input_a, input_b, input_a)
array([1, 2, 3, 3, 3])

有一个内置函数可以执行此操作:clip

output = input_b.clip(max=input_a)

或者如果你想设置 input_b 本身

np.clip(input_b, None, out=input_b)

这里它做的和minimum一样,但它也可以在同一个调用中做maximum。有些版本接受 max 关键字,有些则不接受。

在我的计时中,

clipminimum 略有优势。但我会推荐哪一个看起来意图最清楚。