是否可以禁用Numpy Number Types的Wrap-around

时间:2014-12-10 16:31:20

标签: python numpy

我希望示例uint类型命中0而不是减法包装 - 是否可以在不编写新的c-type的情况下从python中改变这种行为? (例如,减去两个uint8 numpy数组)?

2 个答案:

答案 0 :(得分:2)

Numpy中没有整数上溢/下溢检测,但您可以在计算之前或之后自行测试。 m0在计算后执行此操作,如下所示。

import numpy as np
import timeit

a = np.arange(0, 251, 50, dtype=np.uint8)
b = np.array(a[::-1])

def m0(a, b):
    x = (a-b)
    x[b>a] = 0

def m1(a, b):
    c = (a.astype(np.int16) - b).clip(0, 255).astype(np.uint8)

m0(a, b)
m1(a, b)

a = np.array(a.repeat(1000))  # repeat and copy (copy since I don't remember whether repeat is an indexing trick)
b = np.array(b.repeat(1000))

N = 1000000
print timeit.timeit("m0(a, b)", setup="from __main__ import m0, m1, a, b", number=N)
# 1.7734951973
print timeit.timeit("m1(a, b)", setup="from __main__ import m0, m1, a, b", number=N)
# 3.6973798275

我还将时间与@ Qlaus的方法进行了比较,这也很好,而且它们具有可比性(你不应该非常认真对待50%的速度增益,而是根据你的具体应用测试它们)。另一方面,减法本身大约需要0.6次,所以删除后,m0解决方案的速度提高了约3倍。但另一方面,通常如果您执行一个下溢或溢出的操作,您将执行多个操作,对于这些情况,使用int16可能是最快的。最后,测试您的实际案例将是优化的最佳方法。

答案 1 :(得分:1)

Numpy不对数组类型进行溢出处理。请参阅this讨论或this相关问题。

如果您不太关心速度,可以先将结果保存在int16中,然后剪辑并将其写回uint8数组。

import numpy as np
a = np.arange(5, dtype=np.uint8)
b = np.ones(5, dtype=np.uint8) * 2
print(a-b)  # [254 255   0   1   2]

c = (a.astype(np.int16) - b).clip(0, 255).astype(np.uint8)
print(c)  # [0, 0, 0, 1, 2]