简体   繁体   English

numpy.astype(np.uint8) 如何转换浮点数组? -1.2997805 变成 255

[英]how does numpy.astype(np.uint8) convert a float array? -1.2997805 became 255

this is an execution in ipython3这是在 ipython3 中的执行

In [81]: r2
Out[81]: 
array([-1.2997805, -1.4251276, -1.3047135, ..., -2.0358603, -1.9741256,
       -1.6412157], dtype=float32)

In [82]: r2.astype(np.uint8)
Out[82]: array([255, 255, 255, ..., 254, 255, 255], dtype=uint8)

how is -1.2997805 converted to 255? -1.2997805 如何转换为 255?

ADD : from the comments below(thanks), I tested like this.添加:从下面的评论(谢谢),我是这样测试的。 looks like the float is converted to int, and the modulo 255 (to read it as unsigned int8) is done.看起来浮点数转换为 int,模 255(将其读取为 unsigned int8)已完成。

is first convereted to int. and the it is cut using modulo(%).  
In [98]: b
Out[98]: array([-1.,  0.,  1.])

In [99]: b.astype(np.uint8)
Out[99]: array([255,   0,   1], dtype=uint8)

You converted to unsigned int 8, where -1 correspond to 255, -2 to 254 etc. If you want to get -1, -2 you have to convert it to signed int8 using np.int8:您转换为 unsigned int 8,其中 -1 对应于 255、-2 到 254 等。如果您想获得 -1、-2,则必须使用 np.int8 将其转换为有符号 int8:

>>> np.float32(-2.0358603).astype(np.uint8)
254                                        
>>> np.float32(-2.0358603).astype(np.int8) 
-2                                         

This is an "unsafe cast" according to numpy docs on astype , meaning "any data conversions may be done".根据astype上的 numpy 文档,这是“不安全的转换”,这意味着“可以完成任何数据转换”。 They didn't say how exactly the casting is done and I did not find it in a quick search of the docs, so it may be implementation dependent.他们没有说明转换是如何完成的,我也没有在文档的快速搜索中找到它,所以它可能取决于实现。

My guess is the following: first the 32 bit float is cast to 8 bit signed integer, which defaults to truncating towards zero, ex.我的猜测如下:首先将 32 位浮点数转换为 8 位有符号整数,默认为向零截断,例如。 -1.3 becomes -1. -1.3 变为 -1。 Then a cast from unsigned 8 bit integer to 8 bit unsigned integer, giving a value of 255. Something like然后从无符号 8 位整数转换为 8 位无符号整数,得到 255 的值。

float x = -1.2997805;  # Assume float is 32-bit
(uint8_t)(int8_t)x;

This is not the same as directly converting to 8-bit unsigned int with (uint8_t)x , which gives 0 at least on the platform I tested on (godbolt's x86-64 gcc).这与使用(uint8_t)x直接转换为 8 位 unsigned int 不同,它至少在我测试的平台上给出 0(godbolt 的 x86-64 gcc)。

This kind of thing is very confusing and may even be platform dependent (possibly depending on what OS, numpy version, what the FP hardware decides to do or if the processor even uses 2s complement, etc) so do not ever rely on this behavior without knowing exactly what platform you will be running the code on, and it is poor coding practice anyway.这种事情非常令人困惑,甚至可能依赖于平台(可能取决于什么操作系统、numpy 版本、FP 硬件决定做什么或者处理器是否甚至使用 2s 补码等)所以不要依赖这种行为确切地知道您将在哪个平台上运行代码,无论如何这都是糟糕的编码实践。 Surprisingly, I couldn't find a reference on exactly how numpy's casting rules work.令人惊讶的是,我找不到关于 numpy 的转换规则究竟是如何工作的参考。

The other answers already solve and explain the problem.其他答案已经解决并解释了问题。 I can however suggest an alternative that may be practically useful:但是,我可以建议一个可能实际有用的替代方案:

np.uint8(np.clip(x, 0, 255))

where x is your floating-type array.其中 x 是您的浮动类型数组。

This method ensures negative numbers become 0, and huge positive numbers (> 255) become 255.此方法可确保负数变为 0,而巨大的正数 (> 255) 变为 255。

For example例如

>>> x = [223.2, 888.2, -32, 255.3, 255]
>>> np.uint8(np.clip(x, 0, 255))
array([223, 255,   0, 255, 255], dtype=uint8)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python OpenCV/NumPy:为什么 np.uint8([255]) + np.uint8([255]) 给出的结果是 254 而不是 255? - Python OpenCV/NumPy: why np.uint8([255]) + np.uint8([255]) is giving result 254 instead of 255? 将NumPy np.uint8数组的列表转换为np.unicode_数组 - Convert a list of NumPy np.uint8 arrays to a np.unicode_ array 如何将图像从 np.uint16 转换为 np.uint8? - How to convert an image from np.uint16 to np.uint8? 什么是 np.uint8? - What is np.uint8? 了解从python到float到np.uint8的转换 - Understanding conversion from float to np.uint8 for python 如果我将numpy.narray.view的结果用作2个np.uint8来作为1个np.uint16来理解,该如何理解呢? - How can I understand the order of the result of `numpy.narray.view` if I use it to view 2 `np.uint8` as 1 `np.uint16`? 在运算符表达式的结果上调用函数? (掩码== instance_id).astype(np.uint8) - Calling function on result of operator expression? (mask == instance_id).astype(np.uint8) 有没有办法将 quint8 pytorch 格式转换为 np.uint8 格式? - Is there a way to convert the quint8 pytorch format to np.uint8 format? numpy.astype 与 numba 的非常奇怪的结果 - very strange results of numpy.astype with numba 对于numpy.astype的copy属性感到困惑 - confused about the `copy` attribution of `numpy.astype`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM