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.

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?

Tags:  , , , ,

Answer

  1. Avatar for 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 usando pd.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:

    frame_lms = np.zeros((18000, 477, 3))
    for i, frame in enumerate(video):
        for j, landmark in enumerate(frame):
            x = landmark.x
            y = landmark.y
            xy = np.array([x,y])
            frame_lms[i,j] = xy
    df = pd.DataFrame(frame_lms.reshape((18000, -1)), columns=['lm_{}'.format(i) for i in range(1431)])
    df.to_csv('save.csv')
    

    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 que 477*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.

Comments are closed.