0

I have received the data from a socket. In Matlab, this data is converted into single precision by the following function

data_cal_rx = typecast(data_tcp2, "single");

Now I would like to have the same function in Python. Searching from google and Stack overflow, I saw that the single precision in Python is numpy.float32. So I replace by the following function:

import numpy as np
data_cal_rx = np.float32(data_tcp2)

data_tcp2 in Matlab is an array interger numbers with: class: uint8 dimension: 1x70848

however, when I received data_tcp2 by socket in Python, it is displayed as:

... \x00\x00C\x00 QE\x00 \x04E\x00 'E\x00BE\x00D\x00\x00LE\x00\x00\x10*E\x00`\x00@D\x00\x10+\x00\x00C\x000I\x00\x00A\x00\x16\x00\x13\x00 ...

And I got this error from the terminal in python:

ValueError: could not convert string to float:

It could be a problem with socket in python? Any help or idea would be greatly appreciated.

Thank you very much

fpga
  • 11
  • 1
  • 4
  • Sorry for the mistake in python: it must be np.float32(data_tcp2) – fpga Oct 18 '22 at 14:41
  • "it does not work as I want" What is the result? Why does it not match your expectation? – Cris Luengo Oct 18 '22 at 14:42
  • Sorry for unclear clarification, I have the code octave and python, from which I can compare the results. In python, after the "data_cal_rx = np.float32(data_tcp2)", It print out the data which received from the socket and I got the error: Aborted (core dumped) – fpga Oct 18 '22 at 14:53
  • Please read [mre], then [edit] your post accordingly. If `np.float32(data_tcp2)` crashes the program, you've likely found a bug. But it's hard to help you if we don't now what `data_tcp2` is. I assumed it was a number, but maybe it's a different type of object? – Cris Luengo Oct 18 '22 at 15:06
  • Thank you for your opinion, I will modify the post soon – fpga Oct 18 '22 at 15:08

1 Answers1

1

As an example, let's start with 32-bit float array:

orig = np.arange(5, dtype=np.float32)

We'll convert this to a buffer of bytes:

data = orig.tobytes()

This is shown as:

b'\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@'

Note the initial "b", which indicates this is a bytes object, not a string. If your data is actually a string, see at the bottom of this answer.

Now that we've got our buffer of bytes containing the data in the array, we can convert this back to an array of 32-bit floating-point values with:

out = np.frombuffer(data, dtype=np.float32)

(out is now identical to orig).


If data is a string, you need to first cast it to a bytes buffer, which you can do with

data = bytes(data, 'latin1')

The "latin1" part is the encoding. This encoding seems to not change any data when converting from string to bytes.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Thank you Cris for your reply, I have verified the problem, but after converting back to an array of 32 bit floating-point with " np.frombuffer(data, dtype=np.float32)", I got this error: ValueError: buffer size must be a multiple of element size. I tried to change dtype into many type of datq, but it always display this error. – fpga Oct 20 '22 at 15:26
  • @fpga Yes, if your buffer is composed of 32-bit floats, then its length must be a multiple of 4 bytes. `len(data)` should tell you how many bytes you have. This error is a problem with your input or your assumptions, not with the solution. – Cris Luengo Oct 20 '22 at 15:28
  • At least I know that data_tcp2 is . Can you explain more why I have to use data = bytes(data, 'utf-8') instead of data = orig.tobytes(). Both of them is used to converting into the – fpga Oct 20 '22 at 15:29
  • @fpga You cannot convert a `str` object to `bytes` using `tobytes()`. There is no `str.tobytes()`. If your input is a `str`, then you need to convert it to a `bytes` buffer, and the conversion requires an encoding. Please try the `latin1` encoding (see https://stackoverflow.com/a/42795285/7328782). – Cris Luengo Oct 20 '22 at 15:37