Encadenamiento de operaciones con uint8 vs int64.

Tengo dos funciones que se comportan de la misma manera con int64 pero funcionan de manera diferente con uint8:

A_int64 = np.array([1, 2, 3]) B_unit8 = A.astype(np.uint8) def scale_image(image): minv = np.amin(image) maxv = np.amax(image) result = (255 * (image - minv) / (maxv - minv)) return result.astype(np.uint8) def scale_image_multiple_lines(image): minv = np.amin(image) maxv = np.amax(image) image = image - minv image = image / (maxv - minv) image = image * 255 return image.astype(np.uint8) print(scale_image(A_int64)) # [ 0 127 255] print(scale_image_multiple_lines(A_int64)) # [ 0 127 255] print(scale_image(B_unit8)) # [ 0 127 127] print(scale_image_multiple_lines(B_unit8)) # [ 0 127 255] 

El que no funciona como está previsto es print(scale_image(B_unit8)) # [ 0 127 127]

Mi conjetura es que la versión multilínea funciona con ambos tipos de datos porque se lanza antes. Sin embargo, dado que no creo que esté tratando con negativos (rest el valor mínimo, pero no más que eso, no creo) ¿por qué debería hacer una diferencia?

Estás medio a la derecha. También es el orden de las operaciones.

En la primera función estás multiplicando por 255 primero, luego dividiendo por max-min. El primero da un desbordamiento en la última posición -> (0, 255, 254) luego truedivide por 2 y echamos a uint8

El segundo se divide por dos primero (lo que implica una conversión a flotar), por lo que la multiplicación subsiguiente por 255 no se desborda.