The default dtype for integers in a Pandas Series is int64 -- a signed 64-bit integer.

In [82]: pd.Series([-2692]).dtype
Out[82]: dtype('int64')

If you use astype to convert the dtype to uint16 -- an unsigned 16-bit integer -- then int64 values which are outside the range of ints representable as uint16s get cast to uint16 values. For example, the negative int64 -2692 gets mapped to 62844 as a uint16:

In [80]: np.array([-2692], dtype='int64').astype('uint16')
Out[80]: array([62844], dtype=uint16)

Here is the range of ints representable as int64s:

In [83]: np.iinfo('int64')
Out[83]: iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)

And here is the range of ints representable as uint16s:

In [84]: np.iinfo('uint16')
Out[84]: iinfo(min=0, max=65535, dtype=uint16)

To debug problems like this it is useful to isolate a toy example which exhibits the problem. For example, if you run

for i in range(0,originalN):
    monthstoadd = all_treatments.iloc[i,emcolix].astype('uint16')
    if monthstoadd == 62844:
        print(all_treatments.iloc[i,emcolix])
        print(all_treatments.iloc[i,emcolix].dtype)
        break

then you would see the value of all_treatments.iloc[i,emcolix] before calling astype, and also the dtype. This would be a good starting point to discover the source of the problem.

Answer from unutbu on Stack Overflow
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ declaring an unsigned integer 16 in python for bit shift operation
r/learnpython on Reddit: Declaring an Unsigned Integer 16 in Python for Bit Shift Operation
October 29, 2023 -

SOLVED: 3 Solutions:

  1. using Numpy : np.uint16()

  2. Using CTypes : ctypes.c_uint16()

  3. Using Bitwise : & 0xFFFF


Hi, I'm trying to convert this code to Python from Go / C. It involves declaring a UInt16 variable and run a bit shift operation. However cant seem to create a variable with this specific type. Need some advise here.

Go Code:

package main

import "fmt"

func main() {

var dx uint16 = 38629

var dy uint16 = dx << 8

fmt.Println(dy) //58624 -> Correct value

}

Python Code:

dx = 38629

dy = (dx << 8)

print(dy) # 9889024 -> not the expected value

print(type(dx)) # <class 'int'>

print(type(dy)) # <class 'int'>

I cant seem to figure out a way to cast or similar function to get this into an Unsigned Int 16.\

Please help.

Discussions

Newest 'uint16' Questions - Stack Overflow
I am creating a python OPC UA client based on opcua-asyncio github (https://github.com/FreeOpcUa/opcua-asyncio) to read values in an instrument that has a server already set up. My problem lies in ... ... I am trying to register two 16bit images. One is a .dcm CT series and the other is TIFF image. Both are uint16 ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
BUG: uint16 inserted as int16 when assigning row with dict
Inserting a row with a dict, uint16 values are converted to int16 and the value conversion does not preserve the correct value. This also happens when assigning into an existing object-typed column (the conversion sequence seems to be -> int16 -> int in that case). It's expected the dtype is preserved - uint16 if possible, or an int which is large enough to represent the value. python ... More on github.com
๐ŸŒ github.com
8
June 9, 2022
python - Conversion of image type int16 to uint8 - Stack Overflow
I have an image with data type int16. So when I have to convert its range to 0-255, I got two ways to do that in Python. 1) Use numpy.uint8 function directly 2) Use OpenCV cv2.normalize function ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
python - Conversion uint8 to int16 - Stack Overflow
Is there anyway I could get sharp/black background as per img5 after converting to int16? Any help would be appreciated. ... We can't see your images. ... are you sure it's int16 (signed)? are you sure it's not uint16 (unsigned)? More on stackoverflow.com
๐ŸŒ stackoverflow.com
Top answer
1 of 1
4

Your data corruption is caused by integer overflow.

Once a numpy integer goes outside the range of a datatype (0-255 for uint8), the value overflows and wraps around to 0 again.

For example:

np.uint16(255).astype(np.uint8) == 255
np.uint16(256).astype(np.uint8) == 0
np.uint16(258).astype(np.uint8) == 2
np.uint16(260).astype(np.uint8) == 4
np.uint16(511).astype(np.uint8) == 255
np.uint16(512).astype(np.uint8) == 0
np.uint16(514).astype(np.uint8) == 2
np.uint16(516).astype(np.uint8) == 4

A simple rescale will work, e.g.

data_8bit = ((data - data.min()) / (data.max() - data.min()) * 255).astype(np.uint8)

But you'll get a much nicer looking image if you rescale per band and even better with a per band percentile stretch similar to what most GIS software does, such as [2, 98] or [1, 99]. E.g.

import rasterio
import numpy as np

input_tiff = "test_uint16.tif"
output_tiff = "test_uint8.tif"

percentiles = [1, 99]

with rasterio.open(input_tiff) as src:
    profile = src.profile
    profile.update(dtype=rasterio.uint8)

    with rasterio.open(output_tiff, 'w', **profile) as dst:
        for i in range(src.count):
            band = i+1
            data = src.read(band, masked=True)

            # data.compressed() returns an array of non-masked pixel values
            pmin, pmax = np.percentile(data.compressed(), percentiles)

            # rescale 0-1
            data = (data - pmin) / (pmax - pmin)

            # Ensure data is >= pmin <= pmax
            data[data<0] = 0
            data[data>1] = 1

            # Make it 0-255 8bit unsigned.
            data_int8 = (data * 255).astype(np.uint8)

            dst.write(data_int8, band)
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ tagged โ€บ uint16
Newest 'uint16' Questions - Stack Overflow
I'm having trouble in a data type conversion from float64 to uint16. If I have an array of floats and I try to convert it with array_uint16 = array_float64.astype(np.uint16) is there a sort of "...
๐ŸŒ
GitHub
github.com โ€บ pandas-dev โ€บ pandas โ€บ issues โ€บ 47294
BUG: uint16 inserted as int16 when assigning row with dict ยท Issue #47294 ยท pandas-dev/pandas
June 9, 2022 - Inserting a row with a dict, uint16 values are converted to int16 and the value conversion does not preserve the correct value. This also happens when assigning into an existing object-typed column (the conversion sequence seems to be -> int16 -> int in that case). It's expected the dtype is preserved - uint16 if possible, or an int which is large enough to represent the value. python ...
Author ย  bluss
Top answer
1 of 2
19

All of these do different things.

np.uint8 considers only the lowest byte of your number. It's like doing value & 0xff.

>>> img = np.array([2000, -150, 11], dtype=np.int16)
>>> np.uint8(img)
array([208, 106,  11], dtype=uint8)

cv2.normalize with the cv2.NORM_MINMAX norm type normalises your values according to the normalisation function

img_new = (img - img.min()) * ((max_new - min_new) / (img.max() - img.min())) + min_new

It effectively changes one range to another and all the values in the between are scaled accordingly. By definition the original min/max values become the targetted min/max values.

>>> cv2.normalize(img, out, 0, 255, cv2.NORM_MINMAX)
array([255,   0,  19], dtype=int16)

uint8 in Matlab simply saturates your values. Everything above 255 becomes 255 and everything below 0 becomes 0.

>> uint8([2000 -150 11])

ans =

  255    0   11

If you want to replicate Matlab's functionality, you can do

>>> img[img > 255] = 255
>>> img[img < 0] = 0

Which one you want to use depends on what you're trying to do. If your int16 covers the range of your pixel values and you want to rescale those to uint8, then cv2.normalize is the answer.

2 of 2
2

the simply way to convert data format is to use the following formula. In this case it is possible to convert any array to a new custom format.

# In the case of image, or matrix/array conversion to the uint8 [0, 255] 
# range

Import numpy as np

new_data = (newd_ata - np.min(new_data)) * ((255 - 0) / (np.max(new_data) - 
np.new_data))) + 0
Find elsewhere
๐ŸŒ
Reddit
reddit.com โ€บ r/python โ€บ numpy : why cant numpy cast uint in int
r/Python on Reddit: Numpy : why cant numpy cast uint in int
June 1, 2015 -

It seems that numpy cannot "safely" cast uint into int while using union1d operation. Is there a particular reason why? While i understand why you cannot cast float to int in a safe way, or int to uint, the reason for not being able to cast from uint to int is nebulous to me.

a = np.array([0,1,2,3],dtype='uint')
b = np.array([4,5,6],dtype='int')
c = np.union1d(a,b)
print(c.dtype)

The above example prints float64. Also, the following line returns False :

np.can_cast('uint','int')

The next example can cast without trouble :

np.array(np.array([0,1,2],dtype='uint'),dtype='int')
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 72563282 โ€บ how-to-use-c-sharp-uint16-in-python
.net - How to use C# UInt16[,] in python - Stack Overflow
I can do the conversion only by looping on the matrix, reading each element and assigning its value to the respective position in another numpy matrix, but this solution is very slow. Is there a faster conversion method which can utilize numpy vectorization ? ... import clr import os import numpy as np dll_name = os.path.join(os.path.abspath(os.path.dirname(__file__)), ("mydll") + ".dll") clr.AddReference(dll_name) from mynamespace import myclass myobject = myclass() numpy_matrix = np.empty([80,260],dtype = np.uint16) SystemInt16_matrix = myobject.Getdata() for i in range(20): for j in range(32): numpy_matrix[i,j]=SystemInt16_matrix[i,j]
๐ŸŒ
PyTorch Forums
discuss.pytorch.org โ€บ vision
Doubt with torch.from_numpy with uint16 and how to_tensor manage these kinds of images - vision - PyTorch Forums
June 22, 2020 - Hi, I have a doubt related to the function torch.from_numpy. Iโ€™m trying to convert a numpy array that contains uint16 and Iโ€™m getting the following error: TypeError: canโ€™t convert np.ndarray of type numpy.uint16. The only supported types are: float64, float32, float16, int64, int32, int16, ...
๐ŸŒ
Tonysyu
tonysyu.github.io โ€บ scikit-image โ€บ user_guide โ€บ data_types.html
Image data types and what they mean โ€” skimage v0.6dev docs
For example, if youโ€™re looking ... to span the full range would make background noise look like markers. Sometimes, however, you have images that should span the entire intensity range but do not. For example, some cameras store images with 10-, 12-, or 14-bit depth per pixel. If these images are stored in an array with dtype uint16, then the ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ how-to-convert-signed-to-unsigned-integer-in-python
How to convert signed to unsigned integer in Python ? - GeeksforGeeks
April 5, 2021 - The int data type in python simply the same as the signed integer. A signed integer is a 32-bit integer in the range of -(2^31) = -2147483648 to (2^31) - 1=2147483647 which contains positive or negative numbers. It is represented in two's complement notation. An unsigned integer is a 32-bit non-negative integer(0 or positive numbers) in the range of 0 to 2^32-1. So, in this article let us know how to convert signed integer to unsigned integer in python.