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:
- Mi valor sin procesar es un dato de 4 bytes:
b'\x9a#\xe6\x00'
=[154, 35, 230, 0]
=[0x9A, 0x23, 0xE6, 0x00]
- Tomo el último byte y lo coloco en el primero:
b'\x00\x9a#\xe6'
=[0, 154, 35, 230]
=[0x00, 0x9A, 0x23, 0xE6]
- 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("C"))" 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)…>
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 comonumpy.left_shift
ynumpy.right_shift
.Por ejemplo, para desplazar el último byte de cada valor de 4 bytes al primer byte, puedes usar
numpy.left_shift
ynumpy.right_shift
de la siguiente manera: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.>