I'm looking for a faster function to use than Pythons in built "to_bytes". I need the parameters that is passed into "to_bytes".
(Example: list of data, byte_size and byte order).
Any help would be greatly appreciated!
CodePudding user response:
Not a full answer but a pointer to a possible solution. np.view( dtype = np.uint8
can be used to get a byte by byte view of an array.
import numpy as np
np.random.seed( 1234 )
arr = np.random.randint( 10000, size = 10, dtype = np.int16 ) - 2000
arr
# array([ 6915, -682, 6002, 5221, 2445, 5540, 5347, -1336, 317, 4137], dtype=int16)
b_arr = arr.view( np.uint8 ).reshape( -1,2 )
b_arr
# Col0 Col1 = Res0
# array([[ 3, 27], # 3 27*256 = 6915
# [ 86, 253], # 86 253*256 = 64854 - 65536 = -682 Subtract 65536 if Res0 > 32767
# [114, 23],
# [101, 20],
# [141, 9],
# [164, 21],
# [227, 20],
# [200, 250],
# [ 61, 1],
# [ 41, 16]], dtype=uint8)
The above can be manipulated as required to get little/big endian. np.dtype
lets data be in 1, 2, 4, or 8 byte layout. Then ignore the columns that aren't required.
The endianness of the resulting b_arr
will depend on the endianness of the processor running the code.
Edit Further ideas.
The byte order of a system is in the sys library. A possible function np_to_bytes
:
import sys
byte_lu = [ np.int8, np.int8, np.int16, np.int32, np.int32, np.int64, np.int64, np.int64, np.int64]
cols_lu = [ 1, 1, 2, 4, 4, 8, 8, 8, 8, 8 ]
def np_to_bytes( int_list, n_bytes, endian = sys.byteorder ):
arr = np.array( int_list, dtype = byte_lu[ n_bytes ])
b_arr = arr.view( np.uint8 ).reshape(-1, cols_lu[ n_bytes ])
if sys.byteorder != endian:
b_arr = b_arr[ :, ::-1] # Reverse the columns to change the endian.
if sys.byteorder != endian:
b_arr = b_arr[ :, ::-1] # Reverse the columns to change the endian.
if endian == 'little':
return b_arr[ :, : n_bytes ]
return b_arr[ :, -n_bytes: ]