Archivos de la categoría Trucos

Truco Python. Agrupar variable en función de la frecuencia

Me ha surgido la necesidad de crear una nueva variable en un data frame a partir de la frecuencia de otra, es decir, quedarme con los valores más frecuentes y aplicar una categoría resto para aquellos valores que no estén en los más frecuentes. Para realizar esto se me ha ocurrido la siguiente función en Python:

def agrupa_frecuencia (var_origen, var_destino, df, grupos, valor_otros):
    df_grp= df[var_origen].value_counts()
    list_grp = list(df_grp.iloc[0:grupos,].index)
    df[var_destino] = df[var_origen].map(lambda x: x if x in list_grp else valor_otros, na_action='ignore')

Es una función con más parámetros que líneas, pero necesitamos una variable de origen, una variable de destino que será la que calcularemos, el data frame sobre el que realizamos la tarea, el número de grupos más otro que será el "resto" y dar un valor a ese "resto". La función lo que hace es una tabla de frecuencias ordenada descendentemente con .value_counts() y creamos una lista con el número de grupos que deseamos. Por último mediante lambdas si la variable origen está en la lista generada anteriormente le asignamos el mismo valor, en caso contrario asignamos el valor "resto". Es una programación sencilla, seguramente haya una función específica en sckitlearn para agrupar variables en base a la frecuencia, pero no la he encontrado y he tardado más en buscarla que en hacerla.

Como es habitual os pongo un ejemplo de uso para que podáis ver como funciona:

personas = 1000
grupo = pd.DataFrame(np.random.poisson(15,personas))
grupo['clave']=0
valor = pd.DataFrame(np.random.uniform(100,10000,personas))
valor['clave']=0
df = pd.merge(grupo,valor,on='clave')
del df['clave']
df.columns = ['grupo', 'valor']
df['grupo'].value_counts()

Vemos que grupo crea muchos valores y vamos a agrupar la variable del data frame de forma que los 10 más frecuentes toman su valor y los demás serán un resto:

agrupa_frecuencia('grupo', 'grupo_nuevo', df, 10, 99)
df['grupo_nuevo'].value_counts()

Parece que funciona, si mejoráis, actualizáis o encontráis pegas...

Preparar nuestros datos para sklearn. Pasar de string a número

Cuando trabajamos con python y sklearn necesitamos que todos los datos que vamos a modelizar sean númericos, si tenemos variables carácter necesitamos previamente transformarlas a números. La forma más rápida para realizar esta tarea es emplear preprocesing de sklearn:

import pandas as pd
dias = {'dia': ['lunes','martes','viernes','miercoles','jueves','martes','miercoles','jueves','lunes']}
dias = pd.DataFrame(dias)
dias

Creamos un data frame a partir de una diccionario que se compone de los días de la semana ahora vamos a codificar las etiquetas con el LabelEncoder de sklearn:

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(dias['dia'])

Podemos listar las clases:

list(le.classes_)

Me gustaría destacar que hay que tener especial cuidado con el orden de las codificaciones porque es un orden léxico-gráfico, no va por orden de aparición:

dias = le.transform(dias['dia'])
dias

Ahora ya estamos en disposición de poder emplear sklearn para entrenar nuestro modelo.

Pasando de SAS a R. Primer y ultimo elemento de un campo agrupado de un data frame

Las personas que están acostumbradas a trabajar con SAS emplean mucho los elementos first, last y by, en el blog hay ejemplos al respecto, en R podemos hacer este trabajo con la librería “estrella” dplyr de un modo relativamente sencillo. A continuación se presenta un ejemplo para entender mejor como funciona, creamos un conjunto de datos aleatorio:

id <- rpois(100,20)
mes <- rpois(100,3)+1
importe <- abs(rnorm(100))*100

df <- data.frame(cbind(id,mes,importe))

Tenemos un identificador, una variable mes y un importe y deseamos obtener el menor importe por mes el primer paso a realizar es ordenar el data frame de R por ese identificador, el mes y el importe en orden descendente:

df <- df[with(df,order(id,mes,-importe)),]

Una vez ordenado el data frame de R tenemos que seleccionar el último elemento por id para seleccionar aquellos clientes con menor importe:

library(dplyr)
df_bajo_importe <- df %>% group_by(id) %>% filter(row_number()==n())

Si deseamos seleccionar el mayor importe hacemos lo mismo:

library(dplyr)
df_bajo_importe <- df %>% group_by(id) %>% filter(row_number()==1)

Las funciones group_by unidas a filter(row_number) equivalen a esos first y last de SAS. Saludos.

Truco Python. Reemplazar una cadena de caracteres en los nombres de las columnas de un data frame

Más largo el título de la entrada que la entrada en si misma. Tenemos un conjunto de datos que os podéis descargar de este link que ya es conocido. Os descargáis los datos y creamos un data frame que tiene 10.000 registros y 251 columnas, casi todas se llaman attx y queremos cambiar el nombre a columna_x. Mi sugerencia para hacerlo vía pandas es:

import pandas as pd
df = pd.read_csv('C:\\temp\\wordpress\\au2_10000.csv')
df.head()

df.columns = df.columns.str.replace('att','columna_')
df.head()

Espero que sea de utilidad. Saludos.

Parámetros en las consultas de Hive. Ejemplo con fechas

Soy cinturón blanco de Hive pero aprovecho el blog para mostraros como he añadido unas variables a mi consulta de Hive, en realidad espero que algún alma caritativa me indique alguna forma más elegante. Necesito que mis consultas vayan parametrizadas por fechas que hacen mención a particiones de la tabla, estas particiones no son variables fecha, son string con el formato YYYYMMDD así que es necesario transformar las variables para realizar operaciones con ellas. En este caso tengo una fecha inicio y quiero irme tres meses hacia atrás:

set inicio="20161231";
set f_aux = add_months(from_unixtime(unix_timestamp(${hiveconf:inicio} ,'yyyyMMdd'), 'yyyy-MM-dd'),-3);
set f_mes_menos3 = from_unixtime(unix_timestamp(${hiveconf:f_aux} ,'yyyy-MM-dd'), 'yyyyMMdd');

Con set defino las variables de mi entorno a las que yo referencio como ${hiveconf:variable}, desconozco si hay otra forma mejor de hacerlo y transformo de caracter a fecha con from_unixtime + unix_timestamp para así poder usar la función add_months que no me funcionaba con string. Después deshago el cambio y ya tengo otra variable a partir de la primera, puedo automatizar mis parámetros. ¿Lo estoy haciendo bien?

Truco Excel. Unir todos los libros en una hoja

unir_excel1

Los trucos Excel referentes a la unión de varios libros en uno tienen mucho éxito en esta web, además era necesario crear una versión que uniera de forma horizontal. No es una unión como la pueda hacer Power Query de anexar tablas con cierto sentido teniendo en cuenta el nombre de las columnas y demás, se trata
de unir todas las celdas de un conjunto de libros de forma horizontal en otro libro resultante como ilustra la figura de arriba. Se unirán todos los campos unos encima de otros independientemente de si se llaman igual o no, si queremos anexar tablas es recomendable usar herramientas más específicas. El funcionamiento es muy sencillo pero
lo vamos a ilustrar con imágenes, el primer paso es pulsar directamente el botón y seleccionar los archivos a unir:

unir_excel2

Ahora sólo tenemos que especificar el archivo de destino, puede existir o no, el proceso lo sustituye:

unir_excel3

Y et voilá! Ya tenemos nuestro archivo resultante Sigue leyendo Truco Excel. Unir todos los libros en una hoja

Truco Excel. Actualizar el filtro de todas las tablas dinámicas de mi libro

Traigo hoy al blog una macro de Excel que nos permite recorrer todas las hojas de un libro y dentro de las hojas nos permite recorrer todas las tablas dinámicas y actualizar un campo. Cuando tenemos un informe que se basa en tablas dinámicas y tiene una actualización mensual nos podemos encontrar con la necesidad de cambiar sólo un elemento de la tabla dinámica para actualizar el informe. Este era el caso de mi compañera, hay una entrada en el blog que ya trataba el tema pero esta nueva macro supone otra vuelta de tuerca sobre ella, no sólo recorre y actualiza todas las tablas dinámicas de una hoja, además lo hace de todo el libro. El código de Visual Basic para Excel es:

Sub filtros()
'Macro creada por www.analisisydecision.es

Dim pt As PivotTable
Dim actual, nuevo As String
    actual = 201701
    nuevo = 201702

For i = 1 To Worksheets.Count

Sheets(i).Activate
For Each pt In ActiveSheet.PivotTables
pt.PivotFields("mes").EnableMultiplePageItems = True
With pt.PivotFields("mes")
.PivotItems(nuevo).Visible = True
.PivotItems(actual).Visible = False
End With
Next pt
Next i

En PivotFields ponemos el nombre del campo que deseamos actualizar. Evidentemente necesitamos esconder el valor actual y poner el valor nuevo recorriendo todas las hojas con el bucle For i = 1 To Worksheets.Count y recorriendo todas las tablas dinámicas de cada hoja con For Each pt In ActiveSheet.PivotTables. Lo que si necesitó estar activo es seleccionar varios elementos del campo que deseamos actualizar y por ello fue necesario poner EnableMultiplePageItems = True no llegamos a entender el motivo pero es importante que “Seleccionar varios elementos” esté activo en la tabla dinámica. Espero que estas pocas líneas de código os sean de utilidad, por aquí han automatizado mucho trabajo manual. Saludos.

Nuevo mapa por provincias en Excel de España. Actualiza los colores en RGB

Mapa_excel_provincias_españa_nuevo

A raiz de esta entrada Otto F. Wagner me envió hace unos meses una nueva versión del conocido mapa de provincias de España en Excel y tenía pendiente subirlo a la web. La diferencia con los anteriores es que puedes elegir el color de inicio y el color de fin jugando con RGB:

Mapa_excel_provincias_españa_nuevo2

------Descarga aquí la nueva versión en formato ZIP-----------