La forma más rápida de almacenar y guardar datos de coordenadas en un bucle.
Obtengo puntos de referencia faciales para cada fotograma en un video. Hay 477
puntos de referencia y cada uno es un vector de forma (3,)
.
Tengo un video de 10 minutos a 30 fps. Esto significa que tengo 18000
arreglos de forma (477,3)
. Quiero almacenar toda esta información en un dataframe de pandas donde cada fila es un fotograma y tiene 477 columnas, una para cada arreglo (3,)
.
Actualmente, estoy haciendo lo siguiente:
frame_lms = []
for frame in video:
landmark_dict = {}
lm_count = 0
for landmark in frame:
x = landmark.x
y = landmark.y
xy = np.array([x,y])
landmark_dict[f"lm_{lm_count}"] = xy
lm_count+=1
frame_lms.append(landmark_dict)
df = pd.DataFrame.from_dict(frame_lms)
df.to_csv('save.csv')
Se me ocurrió almacenarlo todo en una lista de diccionarios, agregarlo a una lista y luego guardarlos, basado en investigaciones que muestran que from_dict
es la forma más rápida de crear un dataframe de pandas. Sin embargo, este proceso sigue siendo lento porque tengo que mantener frame_lms
en memoria, lo cual se vuelve enorme a medida que agrego arreglos (477,3)
en él.
¿Cuál es la forma más eficiente computacionalmente para resolver un problema como este?
davy.ai
Una forma de hacer este proceso más eficiente computacionalmente sería crear directamente un array de numpy con la forma
(18000, 477, 3)
, donde la primera dimensión representa el número de fotograma, la segunda dimensión representa el número de marcador y la tercera dimensión representa las coordenadas x e y. Luego puedes convertir este array de numpy en un dataframe de pandas usandopd.DataFrame()
. Esto elimina la necesidad de la lista intermedia de diccionarios y será más rápido y eficiente en memoria. Aquí tienes un ejemplo de implementación:En esta implementación, inicializamos un array de numpy
frame_lms
con forma(18000, 477, 3)
y recorremos cada fotograma y marcador, almacenando las coordenadas x e y en la posición correspondiente en el array. Luego remodelamos el array en un array de numpy 2D con forma(18000, 1431)
(ya que477*3=1431
), lo convertimos en un dataframe de pandas con nombres de columna adecuados y lo guardamos en un archivo CSV.Esta implementación debería ser más rápida y eficiente en memoria que la implementación original.