4

I have a numpy array A of two bytes which I want to combine into an int32. How do I do casting which combines array elements to create different datatype?

6
  • Example and expected result? Can you work with the data before it gets into an ndarray? If so, example of the raw data please. minimal reproducible example Commented Nov 15, 2021 at 23:31
  • I have.a packet I receive, I convert it to a numpy ubyte array. I want to slice sections of the array and combine them. For example A[0] is first 8 bits and A[1] is second 8 bits. So B = A[0]<<8+ A[1]. Commented Nov 15, 2021 at 23:43
  • And you need to have it in an ndarray first? why doesn't your B = A[0]<<8+ A[1] solution work? Commented Nov 15, 2021 at 23:44
  • I guess this works, but I eventually want to cast it into a large structured array. With C you can just copy the memory location and cast. How to do with numpy? Commented Nov 16, 2021 at 0:43
  • numpy doesn't work that way. How are you receiving the data? If you are receiving a Python bytes array, like from a socket, then you can use the Python array or struct modules to have those bytes interpreted as halfwords. That's the closest thing to a C-style reinterpret cast. Commented Nov 16, 2021 at 1:54

1 Answer 1

3

Arrays can be 'viewed' with different dtypes, provided the byte counts are correct.

In [265]: arr = np.array([1,11], 'ubyte')
In [266]: arr
Out[266]: array([ 1, 11], dtype=uint8)
In [267]: arr.view('i2')
Out[267]: array([2817], dtype=int16)
In [268]: arr.view('>i2')                # with different endedness
Out[268]: array([267], dtype=int16)
In [269]: arr.view('uint16')
Out[269]: array([2817], dtype=uint16)

int32 requires 4 bytes:

In [270]: arr.view('int32')
Traceback (most recent call last):
  File "<ipython-input-270-4ab2a022f898>", line 1, in <module>
    arr.view('int32')
ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.

Similarly if the bytes were obtained from a bytestring

In [271]: astr = arr.tobytes()
In [272]: astr
Out[272]: b'\x01\x0b'
In [273]: np.frombuffer(astr, 'uint8')
Out[273]: array([ 1, 11], dtype=uint8)
In [274]: np.frombuffer(astr, 'uint16')
Out[274]: array([2817], dtype=uint16)
In [275]: np.frombuffer(astr, '<i2')
Out[275]: array([2817], dtype=int16)
In [276]: np.frombuffer(astr, '>i2')
Out[276]: array([267], dtype=int16)

view with a compound dtype

In [279]: arr.view('b')
Out[279]: array([ 1, 11], dtype=int8)
In [280]: arr.view('b,b')
Out[280]: array([(1, 11)], dtype=[('f0', 'i1'), ('f1', 'i1')])

Shape may need adjustment after such a view.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, the view function is what I was looking for. Lastly do you know if you can cast into a structured array all at once?
see my last edit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.