es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Lectura de bytes y desplazamiento a int32 firmado en Python-numpy.

Tengo una operación para aplicar en Python a más de 10 millones de valores. Mi problema es optimizar la operación actual.
Tengo 2 métodos de trabajo, numpy y python vanilla.

Operación en Python vanilla:

  1. Mi valor sin procesar es un dato de 4 bytes: b'\x9a#\xe6\x00' = [154, 35, 230, 0] = [0x9A, 0x23, 0xE6, 0x00]
  2. Tomo el último byte y lo coloco en el primero: b'\x00\x9a#\xe6' = [0, 154, 35, 230] = [0x00, 0x9A, 0x23, 0xE6]
  3. Lo transformo en un valor entero con signo de 32 bits: -433874432

Carga de archivo:

f = open(path_data, "rb")
while trame := f.read(4):

Operación de datos:

trame = b'\x9a#\xe6\x00'
trame_list = list(trame)  # [154, 35, 230, 0]
trame_list_swap = [trame_list[-1]] + trame_list[:-1]
trame_swap = bytes(trame_list_swap)
result = int.from_bytes(trame_swap, byteorder='little', signed=True)

Operación en Numpy:

Carga de archivo:

datas_raw = numpy.fromfile(path_data, dtype="<i4") #="" datas_raw="numpy.array([-1708923392," 1639068928,="" 2024603392,="" ...])="" #="" len(datas_raw)="12171264" for="" i,="" trame="" in="" enumerate(datas_raw):="" ```="" operación="" de="" datos:="" ```python="" trame="15082394" tmp="list(trame.tobytes(&quot;C&quot;))" tmp.insert(0,="" tmp.pop())="" result="numpy.ndarray(1,"></i4")><i", bytes(tmp))[0]

está haciendo el mismo procesamiento que en la versión vanilla, pero más lento aquí debido a numpy.ndarray que se activa 10 millones de veces…

pregunta:

mi pregunta es la siguiente:

me gustaría que la versión de numpy realice la operación a nivel de bits en todos los valores sin un for loop (que son muy lentos en python)… cualquier otra solución para el problema es bienvenida (no es un problema xy cerrado)… bytes(tmp))[0]=”” ="" está="" haciendo="" el="" mismo="" procesamiento="" que="" en="" la="" versión="" vanilla,="" pero="" más="" lento="" aquí="" debido="" a="" `numpy.ndarray`="" que="" se="" activa="" 10="" millones="" de="" veces...="" pregunta:="" mi="" pregunta="" es="" la="" siguiente:="" me="" gustaría="" que="" la="" versión="" de="" numpy="" realice="" la="" operación="" a="" nivel="" de="" bits="" en="" todos="" los="" valores="" sin="" un="" `for="" loop`="" (que="" son="" muy="" lentos="" en="" python)...="" cualquier="" otra="" solución="" para="" el="" problema="" es="" bienvenida="" (no="" es="" un="" problema="" xy=""></i", bytes(tmp))[0]

está haciendo el mismo procesamiento que en la versión vanilla, pero más lento aquí debido a numpy.ndarray que se activa 10 millones de veces…

pregunta:

mi pregunta es la siguiente:

me gustaría que la versión de numpy realice la operación a nivel de bits en todos los valores sin un for loop (que son muy lentos en python)… cualquier otra solución para el problema es bienvenida (no es un problema xy cerrado)…>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una manera de realizar la operación bitwise en todos los valores del arreglo numpy sin usar un bucle for es utilizar las funciones de operación bitwise de numpy como numpy.left_shift y numpy.right_shift.

    Por ejemplo, para desplazar el último byte de cada valor de 4 bytes al primer byte, puedes usar numpy.left_shift y numpy.right_shift de la siguiente manera:

    # Cargar los datos como un arreglo numpy
    datas_raw = numpy.fromfile(path_data, dtype="<i4")
    
    # extraer el último byte (es decir, 0xff) de cada valor
    last_byte = numpy.bitwise_and(datas_raw, 0xff)
    
    # desplazar el último byte al primer byte
    first_byte = numpy.left_shift(last_byte, 24)
    second_byte = numpy.left_shift(last_byte, 16)
    third_byte = numpy.left_shift(last_byte, 8)
    
    # combinar los bytes desplazados en un solo valor
    result = numpy.bitwise_or(numpy.bitwise_or(first_byte, second_byte), numpy.bitwise_or(third_byte, last_byte))
    

    esto debería ser más rápido que la operación numpy anterior, ya que evita la necesidad de un bucle for y utiliza operaciones vectorizadas en su lugar. #=”” extraer=”” el=”” último=”” byte=”” (es=”” decir,=”” 0xff)=”” de=”” cada=”” valor=”” last_byte=”numpy.bitwise_and(datas_raw,” 0xff)=”” #=”” desplazar=”” el=”” último=”” byte=”” al=”” primer=”” byte=”” first_byte=”numpy.left_shift(last_byte,” 24)=”” second_byte=”numpy.left_shift(last_byte,” 16)=”” third_byte=”numpy.left_shift(last_byte,” 8)=”” #=”” combinar=”” los=”” bytes=”” desplazados=”” en=”” un=”” solo=”” valor=”” result=”numpy.bitwise_or(numpy.bitwise_or(first_byte,” second_byte),=”” numpy.bitwise_or(third_byte,=”” last_byte))=”” “`=”” esto=”” debería=”” ser=”” más=”” rápido=”” que=”” la=”” operación=”” numpy=”” anterior,=”” ya=”” que=”” evita=”” la=”” necesidad=”” de=”” un=”” bucle=”” for=”” y=”” utiliza=”” operaciones=”” vectorizadas=”” en=”” su=””></i4″)

    extraer el último byte (es decir, 0xff) de cada valor

    last_byte = numpy.bitwise_and(datas_raw, 0xff)

    desplazar el último byte al primer byte

    first_byte = numpy.left_shift(last_byte, 24)
    second_byte = numpy.left_shift(last_byte, 16)
    third_byte = numpy.left_shift(last_byte, 8)

    combinar los bytes desplazados en un solo valor

    result = numpy.bitwise_or(numpy.bitwise_or(first_byte, second_byte), numpy.bitwise_or(third_byte, last_byte))
    “`

    esto debería ser más rápido que la operación numpy anterior, ya que evita la necesidad de un bucle for y utiliza operaciones vectorizadas en su lugar.>

Comments are closed.