Filtrar una mega lista de objetos

Sabemos que filtrar una lista en Python puede hacerse con la función filter, que recibe una función booleana y un iterable, por ejemplo una lista.

La historia es esta. Tengo una lista de 455, 864 objetos Occurrence (llamada omega_tree.occurrences) , y quiero filtrar de aquí (remover) 16,380 (de una lista llamada ocs_of_interest). Originalmente pensé en simplemente hacer un filter:

ocs_complements = filter(lambda occurrence : occurrence not in ocs_of_interest , omega_tree.occurrences)

Estaba cansado y decidí dejar la compu corriendo. Cuando regresé a trabajar (12 horas después) el proceso seguía corriendo…

Pensé que tal vez se estaba lo que ocasionaba la demora era el método __hash__ y __eq__ que se utiliza para decidir si un elemento es igual al otro por lo que extraje solo el índice (un mapeo de los objectos Occurrence a Int). Esto hizo, efectivamente, más eficiente el filtrado pero igual, haciendo unas estimaciones a bote pronto me dijeron que posiblemente tardaría unas 10 horas… Rubish!

Me puse a buscar y encontré que la clase Set no solo es útil para remover elementos repetidos dentro de listas pero también hace muy eficiente la busqueda y, en mi caso, filtrado de objectos grandes.

Hice un cast (conversión) a lista para obtener un set. Los resultados fueron sorprendentes!!

%time ofi = set(map(lambda o : o.pk, ocs_of_interest))
%time oo = set(map(lambda o : o.pk ,omega_tree.occurrences))
%time ocs_complements = filter(lambda occurrence : occurrence not in ofi , oo)

CPU times: user 116 ms, sys: 0 ns, total: 116 ms
Wall time: 114 ms
CPU times: user 3.24 s, sys: 8 ms, total: 3.25 s
Wall time: 3.26 s
CPU times: user 136 ms, sys: 0 ns, total: 136 ms
Wall time: 133 ms

Conclusión

Para filtrar una lista grande de objetos conviene convertir la lista a conjunto (Set). El aumento de rendimiento es increiblemente grande!

Published by

Juan Escamilla Mólgora

Hago ecología matemática y computacional para grandes datos ambientales bajo plataformas descentralizadas basadas en la nube. En particular estoy investigando métodos novedosos de fusión de datos mutirelacionados para mejorar los modelos de predicción de especies biológicas. También diseñé y programé el Sistema de Alerta temprana de Incendios para México y Centro América

Deja un comentario

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.