替换 Python NumPy 数组中大于某个值的所有元素

新手上路,请多包涵

我有一个 2D NumPy 数组,想用 255.0.0 替换其中大于或等于阈值 T 的所有值。据我所知,最基本的方法是:

 shape = arr.shape
result = np.zeros(shape)
for x in range(0, shape[0]):
    for y in range(0, shape[1]):
        if arr[x, y] >= T:
            result[x, y] = 255

  1. 最简洁和pythonic的方法是什么?

  2. 有没有更快(可能不那么简洁和/或不那么pythonic)的方法来做到这一点?

这将是用于人体头部 MRI 扫描的窗口/水平调整子程序的一部分。二维 numpy 数组是图像像素数据。

原文由 NLi10Me 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

我认为最快和最简洁的方法是使用 NumPy 的内置 Fancy 索引。 If you have an ndarray named arr , you can replace all elements >255 with a value x as follows:

 arr[arr > 255] = x

我在我的机器上用一个 500 x 500 的随机矩阵运行它,将所有 >0.5 的值替换为 5,平均耗时 7.59 毫秒。

 In [1]: import numpy as np
In [2]: A = np.random.rand(500, 500)
In [3]: timeit A[A > 0.5] = 5
100 loops, best of 3: 7.59 ms per loop

原文由 mdml 发布,翻译遵循 CC BY-SA 4.0 许可协议

因为你实际上想要一个不同的数组,它是 arr 其中 arr < 255255 否则,这可以简单地完成:

 result = np.minimum(arr, 255)

更一般地,对于下限和/或上限:

 result = np.clip(arr, 0, 255)

如果您只想访问超过 255 或更复杂的值,@mtitan8 的答案更笼统,但是 np.clipnp.minimum (或 np.maximum )对你的情况来说更好更快:

 In [292]: timeit np.minimum(a, 255)
100000 loops, best of 3: 19.6 µs per loop

In [293]: %%timeit
   .....: c = np.copy(a)
   .....: c[a>255] = 255
   .....:
10000 loops, best of 3: 86.6 µs per loop

If you want to do it in-place (ie, modify arr instead of creating result ) you can use the out parameter of np.minimum

 np.minimum(arr, 255, out=arr)

要么

np.clip(arr, 0, 255, arr)

out= 名称是可选的,因为参数的顺序与函数定义的顺序相同。)

对于就地修改,布尔索引加快了很多(无需单独制作然后修改副本),但仍然不如 minimum 快:

 In [328]: %%timeit
   .....: a = np.random.randint(0, 300, (100,100))
   .....: np.minimum(a, 255, a)
   .....:
100000 loops, best of 3: 303 µs per loop

In [329]: %%timeit
   .....: a = np.random.randint(0, 300, (100,100))
   .....: a[a>255] = 255
   .....:
100000 loops, best of 3: 356 µs per loop

为了比较,如果你想用最小值和最大值限制你的值,没有 clip 你必须这样做两次,像

np.minimum(a, 255, a)
np.maximum(a, 0, a)

要么,

 a[a>255] = 255
a[a<0] = 0

原文由 askewchan 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题