Home > Software engineering >  Is there a faster way to run a function similar to to_bytes? I had a look through Numpys function li
Is there a faster way to run a function similar to to_bytes? I had a look through Numpys function li

Time:09-22

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: ]
  • Related