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!

Envolver líneas (text wrap) en VIM

Text wrap es el proceso de insertar saltos de línea automágicamente para poder visualizar líneas de texto mas grandes que la ventana del editor de texto (IDE).

Muchos IDEs hacen esto y VIM no es la excepción.

Para activarlo usar:


:set tw='n'

Donde ‘n’ es el número de caracteres por línea.

Para detener el proceso de wrap (envolver) hay que usar ‘n’=0

Modificar margen antes de aplicar wrap

Para modificar este valor usar:

:set wm=k

Donde ‘k’ es el numero de caracteres por tolerar antes de aplicar el wrap (cuando se haya sobrepasado el límite tw)

Soft wrap

Se no se quiere insertar símbolos EOL y únicamente se quiere visualizar saltos de línea úsese:

:set wrap linebreak nolist

Mas información

[N] VIM Shortcuts

My lista de los atajos (shortcuts) más usados en [N]VIM

Substituir texto entre dos marcadores

Ya sabemos que con la teclas [m] + [a-z] creamos un marcador dentro del archivo.

Podemos entonces substituir texto entre cualesquiera par de marcadores utilizando el siguiente comando (en modo Normal).

Supongamos pues que queremos cambiar la palabra ‘Político Priísta’ por ‘Rata’. Dentro del texto:

a

“El poder no lo debe tener y nunca debió haber regresado a Los Pinos ese poder del presidente con el PRI”, manifestó el político priista, quien el domingo a la noche no acompañó a José Antonio Meade Kuribreña en su noche triste..

b


El comando sería el siguiente:

:’a , ‘bs/político priista/rata/gc

Las opciones g y c significan: global (cambiará todas las occurrencias encontradas en cada línea) y confirmation (preguntará por confirmación para sustituir).

Hay más información aquí: https://vim.fandom.com/wiki/Search_and_replace


Cargar datos en R

… y ajustar un modelo GLM

Introducción

Este post quiere ser un pequeño acordeon (chuleta) de ciertas funciones y paquetes en R para hacer análisis espaciales.
Si, he aceptado que hay un montón de cosas que valen la pena en R y este es mi intento de volverme a acercar a ese lenguaje que sigo considerado obscuro y sucio. Sin embargo, a la comunidad de estadística le gusta. Supongo que por razones históricas y la típica ley de potencia de Winners take all… Yo

Supuestos

  • Datos extraidos de Biospytial y guardados en CSV en el backend de Redis.
    • > (Actualizado. el objeto en redis es un pickle de un DataFrame de Pandas. No he encontrado forma trivial de portar estos objetos en R. Se utiliza entonces un formato CSV (estandar) guardado con antelación)
  • Command-line. No hay interfáz gráfica

Preparación

  • Seleccionar un repositorio CRAN (alguno de los dos)
    chooseCRANmirror(graphics=FALSE)
    options(repos='http://cran.rstudio.com/')
  • Cargar driver de Redis
    • library('rredis')
  • Conectar a BD redis
  • redisConnect(host='redis',password='biospytial.')
     
  • Read data from CSV
    TDF = read.csv("/outputs/training_data_sample_puebla_p2_abies_pinophyta.csv")
    PDF = read.csv('/outputs/presence_only_models/predictors/dataset100x100-puebla-p2/0-pred.csv')
     

Definir el modelo

$$ Y(x) = Dist.Road + Pop.denst + vegtype$$ Se procederá a ajustar un modelo GLM con supuestos de independencia en los residuales (i.e. estandard GLM). formula = ‘Pinophyta ~ Dist.to.road_m + Population_m + tipos’ mod_sig = glm(formula, data=TDF, family=binomial()) summary(mod_sig) confint(mod_sig)    


			

Visualizar correlaciones en Python

En este post veremos como graficar correlaciones de una matrix de diseño multidimensional usando un correlograma con Python, Pandas y Seaborn.

Seaborn es una biblioteca para visualizar datos. Posee similares características a R.

Calcular correlaciones

Para hacer esto basta con utilizar el método ‘pandas.DataFrame.corrs()’. El método regresa un dataframe de salida. Esta estructura será utilizada por la funcion ‘heatmap’ de Seaborn.

Código:

Supongamos que tenemos un Pandas DataFrame llamado TDF.

Nota de actualización: Por alguna razón se perdió la imagen original. La estoy sustituyendo por otro correlograma. Este sin embargo no proviene de una “Matríz de diseño” si no de un modelo condicional de autocorrelación espacial. Aquí simplemente convertí la matriz generada por MCMC  que representa regiones geográficas como columnas y muestras (iteraciones) como renglones. El patrón es muy hermoso, da una apariencia textil, aunque no esta relacionado a esto en absoluto pues solo muestra la correlación entre regiones geográficas de un modelo CAR.

El código para desarrollar esto fue hecho en STAN y tengo pensado subirlo pronto. Por lo pronto, aquí les dejo la imágen y el código para visualizarlo.

import seaborn as sb
## El objecto cadenaMCMC fue generado por STAN (extract) 
phidf = pd.DataFrame(cadenaMCMC['phi'])
correlaciones = phidf.corr()
sb.heatmap(correlaciones)

Cómo graficar geometrías de Django (Biospytial)

Hola!

Biospytial utiliza el backend de Django-postgis para representar objetos y geometrías. Por eso es común encontrar objetos del tipo “django.contrib.gis.geos” [Point, Polygon] para poder usar operaciones geométricas.

Hay algunas incompatibilidades con Shapely y en general para plotear directamente usando matplotlib.

Para poder obtener una gráfica de algún objeto geométrico, deberemos utilizar ‘GeoPandas’  y ‘Shapefile’ como intermediario.

Simplemente cargamos las librerias:

from geopandas import GeoSeries
from shapely.wkt import loads

Después simplemente instanciamos un objeto GeoSeries (GeoDataSet) y cargamos el objeto geos.Polygon utilizando el método de representación en WKT.

Revisa el siguiente código para entender

from django.contrib.gis.geos import Point, Polygon
xcoord = -99.76
ycoord = 17.55
p = Point(xcoord,ycoord,srid=4326)
newp = p.buffer(0.08)

from geopandas import GeoSeries
from shapely.wkt import loads

gs = GeoSeries([loads(newp.wkt)])
gs.crs = {'init' : 'epsg:4326'}
gs.plot()

 

 

 

Insertar y quitar comentarios con VIM

Llevo poco tiempo usando NeoVim y me está gustando mucho.

Aquí les describo una manera rápida de seleccionar un bloque de texto y comentarlo.

Vamos a suponer que tenemos el siguiente código en Python y  queremos comentar algunas líneas dentro del ambiente de Model().

with Model() as model: # model specifications in PyMC3 are wrapped in a with-statement
    # Define priors
    sigma = HalfCauchy('sigma', beta=10, testval=1.)
    intercept = Normal('Intercept', 0, sd=20)
    x_coeff = Normal('x', 0, sd=20)

    # Define likelihood
    likelihood = Normal('y', mu=intercept + x_coeff * x,
                        sd=sigma, observed=y)

    # Inference!
    trace = sample(3000, cores=2) # draw 3000 posterior samples

Para comentar en bloque hay que hacer lo siguiente:

  • Teclear [ Ctrl ] + V  — Esto activará el modo “Visual en Bloque”.
  • Movemos el cursor con las flechas o ( teclas JKLH ) para seleccionar todo el bloque que queramos comentar.
  • Si queremos insertar un comentario deberemos cambiar al modo de insertar presionando: [ Shift ] + i (I may’uscula)
  • Si queremos quitar el comentario presionar la tecla [x] (correspondiente a borrar un caracter)
  • Insertamos el símbolo de comentario (e.g. #) . Esto modificará sólo la primera línea.
  • Salir del modo de inserción por bloque con la tecla [ ESC ]

Vim insertará este caracter en todo el bloque seleccionado.

with Model() as model: # model specifications in PyMC3 are wrapped in a with-statement
    # Define priors
#    sigma = HalfCauchy('sigma', beta=10, testval=1.)
#    intercept = Normal('Intercept', 0, sd=20)
#    x_coeff = Normal('x', 0, sd=20)

#    # Define likelihood
#    likelihood = Normal('y', mu=intercept + x_coeff * x,
                        sd=sigma, observed=y)

    # Inference!
    trace = sample(3000, cores=2) # draw 3000 posterior samples