Paquete DataFrames

DataFrames.jl

Es un paquete que nos permite explorar información tabulándola. Este paquete es alternativo y equivalente al famoso paquete “Pandas” de Python.

Como el nombre del paquete lo indica, la información se maneja en una estructuta de datos llamada “dataframe”, el cual es similar a una tabla u hoja de cálculo (como la de Excel). Por lo tanto, el paquete nos permite explorar un dataset, transformarlo y almacenar la información.

Junto a DataFrames se puede utilizar el paquete Queryverse, el cual permite tener a mano diferentes herramientas útiles para: trabajar con archivos, manipular datos y explorarlos; por tanto, permite tener mayor eficiencia.

using Pkg; Pkg.activate("."); Pkg.instantiate() ##Activando enviroment local
 Activating environment at `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`

Los paquetes DataFrames y Queryverse pueden ser añadidos a Julia y luego ser cargados de la forma usual. Se utilizará el paquete Plots, para realizar algunas gráficas y de esta forma visualizar datos.

using Plots, Queryverse, DataFrames ##Importando librerías

Cargando archivos

En Julia existen diversos paquetes que permiten cargar archivos, como el paquete CSV. Sin embargo, el paquete Queryverse permite usar la función load, que permite leer no solo archivos \(^*\).csv sino también archivos: \(^*\).xls, \(^*\).xlsx, \(^*\).dta, \(^*\).sav, entre otros.

Ahora cargaremos el dataset que se estará utilizando para mostrar las bondades del paquete DataFrames.

datatrain = load("./titanic/train.csv");

A continuación se muestra cómo se carga los datos de una archivo \(^*\).xlsx, en el cual se especifica el nombre de la hoja de cálculo (en el caso particular del ejemplo “train”).

datatest = load("./titanic/test.xlsx", "test");

Ahora podemos comprobar que los datos efectivamente ha sido cargado en las variables de ambos archivos.

typeof(datatrain)
CSVFiles.CSVFile
datatest;

A menudo se requerirá que los datos deban ser contenidos en un dataframe, para ello se utiliza el constructor DataFrame del paquete DataFrames. Podrá notar la mejora en la presentación de la tablas cuando se utiliza el paquete mencionado.

Existen varias maneras de crear el dataframe, la primera es:

dftest = DataFrame(datatest)

418 rows × 11 columns (omitted printing of 7 columns)

PassengerIdPclassNameSex
Float64Float64StringString
1892.03.0Kelly, Mr. Jamesmale
2893.03.0Wilkes, Mrs. James (Ellen Needs)female
3894.02.0Myles, Mr. Thomas Francismale
4895.03.0Wirz, Mr. Albertmale
5896.03.0Hirvonen, Mrs. Alexander (Helga E Lindqvist)female
6897.03.0Svensson, Mr. Johan Cervinmale
7898.03.0Connolly, Miss. Katefemale
8899.02.0Caldwell, Mr. Albert Francismale
9900.03.0Abrahim, Mrs. Joseph (Sophie Halaut Easu)female
10901.03.0Davies, Mr. John Samuelmale
11902.03.0Ilieff, Mr. Yliomale
12903.01.0Jones, Mr. Charles Cressonmale
13904.01.0Snyder, Mrs. John Pillsbury (Nelle Stevenson)female
14905.02.0Howard, Mr. Benjaminmale
15906.01.0Chaffee, Mrs. Herbert Fuller (Carrie Constance Toogood)female
16907.02.0del Carlo, Mrs. Sebastiano (Argenia Genovesi)female
17908.02.0Keane, Mr. Danielmale
18909.03.0Assaf, Mr. Geriosmale
19910.03.0Ilmakangas, Miss. Ida Livijafemale
20911.03.0Assaf Khalil, Mrs. Mariana (Miriam")"female
21912.01.0Rothschild, Mr. Martinmale
22913.03.0Olsen, Master. Artur Karlmale
23914.01.0Flegenheim, Mrs. Alfred (Antoinette)female
24915.01.0Williams, Mr. Richard Norris IImale
25916.01.0Ryerson, Mrs. Arthur Larned (Emily Maria Borie)female
26917.03.0Robins, Mr. Alexander Amale
27918.01.0Ostby, Miss. Helene Ragnhildfemale
28919.03.0Daher, Mr. Shedidmale
29920.01.0Brady, Mr. John Bertrammale
30921.03.0Samaan, Mr. Eliasmale

La segunda es más elegante y se utiliza pipe sintax:

dftrain = datatrain |> DataFrame;
typeof(datatrain), typeof(dftrain)
(CSVFiles.CSVFile, DataFrame)

Como nota adicional, el método load también admite pasar como parámetro un String con la una url de donde el conjunto de datos pueda ser descargado, el archivo se guarda en el directorio que contiene el archivo que es ejecutado..

Trabajando con los datos

A continuación, se discutirán sobre alguna de las funciones implementadas en DataFrames para trabajar con los datos tabulados.

Obteniendo información del dataset

Existe un conjunto de funciones que nos permite tener un overview del dataset que se ha cargado. Lo anterior será importante para dar un manejo adecuado a los datos.

Para obtener las columnas del dataframe se utiliza el método names.

names(dftrain)
12-element Array{String,1}:
 "PassengerId"
 "Survived"
 "Pclass"
 "Name"
 "Sex"
 "Age"
 "SibSp"
 "Parch"
 "Ticket"
 "Fare"
 "Cabin"
 "Embarked"
names(dftest)
11-element Array{String,1}:
 "PassengerId"
 "Pclass"
 "Name"
 "Sex"
 "Age"
 "SibSp"
 "Parch"
 "Ticket"
 "Fare"
 "Cabin"
 "Embarked"

Las dimensiones de dataframe se puede obtener con el método size.

size(dftrain)
(891, 12)
size(dftest)
(418, 11)

Una descripción del contenido de las columnas puede realizarse con el método describe. El método entrega información estadística de las columnas y varias propiedades.

describe(dftrain);
describe(dftest)

11 rows × 8 columns (omitted printing of 3 columns)

variablemeanminmedianmax
SymbolUnion…AnyUnion…Any
1PassengerId1100.5892.01100.51309.0
2Pclass2.265551.03.03.0
3NameAbbott, Master. Eugene Josephvan Billiard, Master. Walter John
4Sexfemalemale
5Age30.27260.1727.076.0
6SibSp0.4473680.00.08.0
7Parch0.3923440.00.09.0
8Ticket
9Fare35.62720.014.4542512.329
10CabinA11G6
11EmbarkedCS

Renombrando las columnas

Renombrar una columna es útil cuando los nombres no son descriptivos y legibles.

rename!(dftrain, :PassengerId=>"Id", :Pclass=>"Class", :Sex=>"Gender")

891 rows × 12 columns (omitted printing of 8 columns)

IdSurvivedClassName
Int64Int64Int64String
1103Braund, Mr. Owen Harris
2211Cumings, Mrs. John Bradley (Florence Briggs Thayer)
3313Heikkinen, Miss. Laina
4411Futrelle, Mrs. Jacques Heath (Lily May Peel)
5503Allen, Mr. William Henry
6603Moran, Mr. James
7701McCarthy, Mr. Timothy J
8803Palsson, Master. Gosta Leonard
9913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)
101012Nasser, Mrs. Nicholas (Adele Achem)
111113Sandstrom, Miss. Marguerite Rut
121211Bonnell, Miss. Elizabeth
131303Saundercock, Mr. William Henry
141403Andersson, Mr. Anders Johan
151503Vestrom, Miss. Hulda Amanda Adolfina
161612Hewlett, Mrs. (Mary D Kingcome)
171703Rice, Master. Eugene
181812Williams, Mr. Charles Eugene
191903Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)
202013Masselmani, Mrs. Fatima
212102Fynney, Mr. Joseph J
222212Beesley, Mr. Lawrence
232313McGowan, Miss. Anna "Annie"
242411Sloper, Mr. William Thompson
252503Palsson, Miss. Torborg Danira
262613Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)
272703Emir, Mr. Farred Chehab
282801Fortune, Mr. Charles Alexander
292913O'Dwyer, Miss. Ellen "Nellie"
303003Todoroff, Mr. Lalio
rename!(dftest, :PassengerId=>"Id", :Pclass=>"Class", :Sex=>"Gender")

418 rows × 11 columns (omitted printing of 7 columns)

IdClassNameGender
Float64Float64StringString
1892.03.0Kelly, Mr. Jamesmale
2893.03.0Wilkes, Mrs. James (Ellen Needs)female
3894.02.0Myles, Mr. Thomas Francismale
4895.03.0Wirz, Mr. Albertmale
5896.03.0Hirvonen, Mrs. Alexander (Helga E Lindqvist)female
6897.03.0Svensson, Mr. Johan Cervinmale
7898.03.0Connolly, Miss. Katefemale
8899.02.0Caldwell, Mr. Albert Francismale
9900.03.0Abrahim, Mrs. Joseph (Sophie Halaut Easu)female
10901.03.0Davies, Mr. John Samuelmale
11902.03.0Ilieff, Mr. Yliomale
12903.01.0Jones, Mr. Charles Cressonmale
13904.01.0Snyder, Mrs. John Pillsbury (Nelle Stevenson)female
14905.02.0Howard, Mr. Benjaminmale
15906.01.0Chaffee, Mrs. Herbert Fuller (Carrie Constance Toogood)female
16907.02.0del Carlo, Mrs. Sebastiano (Argenia Genovesi)female
17908.02.0Keane, Mr. Danielmale
18909.03.0Assaf, Mr. Geriosmale
19910.03.0Ilmakangas, Miss. Ida Livijafemale
20911.03.0Assaf Khalil, Mrs. Mariana (Miriam")"female
21912.01.0Rothschild, Mr. Martinmale
22913.03.0Olsen, Master. Artur Karlmale
23914.01.0Flegenheim, Mrs. Alfred (Antoinette)female
24915.01.0Williams, Mr. Richard Norris IImale
25916.01.0Ryerson, Mrs. Arthur Larned (Emily Maria Borie)female
26917.03.0Robins, Mr. Alexander Amale
27918.01.0Ostby, Miss. Helene Ragnhildfemale
28919.03.0Daher, Mr. Shedidmale
29920.01.0Brady, Mr. John Bertrammale
30921.03.0Samaan, Mr. Eliasmale

Accediendo a los elementos de un dataframe

Diferentes formas puede ser aplicado para acceder a los elementos de un dataframe. A continuación se muestran algunas.

Mediante el punto (.col)

dftrain.Name ###Retorna un array
891-element Array{String,1}:
 "Braund, Mr. Owen Harris"
 "Cumings, Mrs. John Bradley (Florence Briggs Thayer)"
 "Heikkinen, Miss. Laina"
 "Futrelle, Mrs. Jacques Heath (Lily May Peel)"
 "Allen, Mr. William Henry"
 "Moran, Mr. James"
 "McCarthy, Mr. Timothy J"
 "Palsson, Master. Gosta Leonard"
 "Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)"
 "Nasser, Mrs. Nicholas (Adele Achem)"
 "Sandstrom, Miss. Marguerite Rut"
 "Bonnell, Miss. Elizabeth"
 "Saundercock, Mr. William Henry"
 ⋮
 "Potter, Mrs. Thomas Jr (Lily Alexenia Wilson)"
 "Shelley, Mrs. William (Imanita Parrish Hall)"
 "Markun, Mr. Johann"
 "Dahlberg, Miss. Gerda Ulrika"
 "Banfield, Mr. Frederick James"
 "Sutehall, Mr. Henry Jr"
 "Rice, Mrs. William (Margaret Norton)"
 "Montvila, Rev. Juozas"
 "Graham, Miss. Margaret Edith"
 "Johnston, Miss. Catherine Helen \"Carrie\""
 "Behr, Mr. Karl Howell"
 "Dooley, Mr. Patrick"

Mediante el símbolo ([:col])

dftrain[:Age] ###Retorna un Array
891-element Array{Union{Missing, Float64},1}:
 22.0
 38.0
 26.0
 35.0
 35.0
   missing
 54.0
  2.0
 27.0
 14.0
  4.0
 58.0
 20.0
  ⋮
 56.0
 25.0
 33.0
 22.0
 28.0
 25.0
 39.0
 27.0
 19.0
   missing
 26.0
 32.0

Mediante índice

dftrain[1,5]  ###Un elemento específico
"male"

En el ejemplo anterior se accedió a solo un dato de la columna, para acceder a toda la columna ser realiza con (:)

dftrain[:,5] ###Retorna un Array
891-element Array{String,1}:
 "male"
 "female"
 "female"
 "female"
 "male"
 "male"
 "male"
 "male"
 "female"
 "female"
 "female"
 "female"
 "male"
 ⋮
 "female"
 "female"
 "male"
 "female"
 "male"
 "male"
 "female"
 "male"
 "female"
 "female"
 "male"
 "male"
dftrain[:,[5]] ###Retorna un DataFrame

891 rows × 1 columns

Gender
String
1male
2female
3female
4female
5male
6male
7male
8male
9female
10female
11female
12female
13male
14male
15female
16female
17male
18male
19female
20female
21male
22male
23female
24male
25female
26female
27male
28male
29female
30male

Se puede acceder a un conjunto de columnas a la vez

dftrain[:,[1,4,5,3]] ###Retorna un DataFrame

891 rows × 4 columns

IdNameGenderClass
Int64StringStringInt64
11Braund, Mr. Owen Harrismale3
22Cumings, Mrs. John Bradley (Florence Briggs Thayer)female1
33Heikkinen, Miss. Lainafemale3
44Futrelle, Mrs. Jacques Heath (Lily May Peel)female1
55Allen, Mr. William Henrymale3
66Moran, Mr. Jamesmale3
77McCarthy, Mr. Timothy Jmale1
88Palsson, Master. Gosta Leonardmale3
99Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female3
1010Nasser, Mrs. Nicholas (Adele Achem)female2
1111Sandstrom, Miss. Marguerite Rutfemale3
1212Bonnell, Miss. Elizabethfemale1
1313Saundercock, Mr. William Henrymale3
1414Andersson, Mr. Anders Johanmale3
1515Vestrom, Miss. Hulda Amanda Adolfinafemale3
1616Hewlett, Mrs. (Mary D Kingcome) female2
1717Rice, Master. Eugenemale3
1818Williams, Mr. Charles Eugenemale2
1919Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)female3
2020Masselmani, Mrs. Fatimafemale3
2121Fynney, Mr. Joseph Jmale2
2222Beesley, Mr. Lawrencemale2
2323McGowan, Miss. Anna "Annie"female3
2424Sloper, Mr. William Thompsonmale1
2525Palsson, Miss. Torborg Danirafemale3
2626Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)female3
2727Emir, Mr. Farred Chehabmale3
2828Fortune, Mr. Charles Alexandermale1
2929O'Dwyer, Miss. Ellen "Nellie"female3
3030Todoroff, Mr. Laliomale3
dftrain[:,[:Id,:Name,:Gender,:Class]] ###Retorna un DataFrame

891 rows × 4 columns

IdNameGenderClass
Int64StringStringInt64
11Braund, Mr. Owen Harrismale3
22Cumings, Mrs. John Bradley (Florence Briggs Thayer)female1
33Heikkinen, Miss. Lainafemale3
44Futrelle, Mrs. Jacques Heath (Lily May Peel)female1
55Allen, Mr. William Henrymale3
66Moran, Mr. Jamesmale3
77McCarthy, Mr. Timothy Jmale1
88Palsson, Master. Gosta Leonardmale3
99Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female3
1010Nasser, Mrs. Nicholas (Adele Achem)female2
1111Sandstrom, Miss. Marguerite Rutfemale3
1212Bonnell, Miss. Elizabethfemale1
1313Saundercock, Mr. William Henrymale3
1414Andersson, Mr. Anders Johanmale3
1515Vestrom, Miss. Hulda Amanda Adolfinafemale3
1616Hewlett, Mrs. (Mary D Kingcome) female2
1717Rice, Master. Eugenemale3
1818Williams, Mr. Charles Eugenemale2
1919Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)female3
2020Masselmani, Mrs. Fatimafemale3
2121Fynney, Mr. Joseph Jmale2
2222Beesley, Mr. Lawrencemale2
2323McGowan, Miss. Anna "Annie"female3
2424Sloper, Mr. William Thompsonmale1
2525Palsson, Miss. Torborg Danirafemale3
2626Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)female3
2727Emir, Mr. Farred Chehabmale3
2828Fortune, Mr. Charles Alexandermale1
2929O'Dwyer, Miss. Ellen "Nellie"female3
3030Todoroff, Mr. Laliomale3

Es posible que, en lugar de indicar cada columna y dependiendo del nombre que posean las columnas, estas puedan ser indicadas por medio de una expresión regular indicado con r\"--\". Lo anterior trata de hacer match con los nombres de las columnas y cuando se encuentre alguna coincidencia del nombre de la columna con la regla descrita por la expresión regular esta es devuelta.

En los ejemplos anteriores se accedió a todas las filas de las columnas, sin embargo, puede accederse a un grupo limitado como se muestra a continuación

dftrain[50:100,[:Id,:Name,:Gender,:Class]];
dftrain[[50,75,100],[:Id,:Name,:Gender,:Class]];

Mediante una condición

dftrain[dftrain.Class.==2,:];

Note como en el ejemplo anterior se utiliza broadcasting. La manera en que funciona lo anterior es de la siguiente forma:

Primero se genera un vector con valores booleanos.

arraybool = dftrain.Class.==2;

Luego el arreglo se pasa en el lugar del primer índice cuado se desea acceder a los elementos del dataframe, el arreglo filtra los datos que serán mostrados (todas las filas que coincidan con el valor booleano true).

dftrain[arraybool,:];

Para mayor legibilidad en el código, lo mejor será usar un conjunto de funciones que nos permiten hacer filtrado de la información, por ejemplo usar el método filter. Usar dichos métodos nos permitirá crear condiciones más robustas, complejas y claras.

En el ejemplo que sigue se utiliza el paquete Pipe, el cual mejora la utilidad del uso de pipe, teniendo la posibilidad de usar funciones y pasar argumentos.

Pkg.add("Pipe"); using Pipe;
   Updating registry at `~/.julia/registries/General`
  Resolving package versions...
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Manifest.toml`
@pipe dftrain |> filter(x->x.Class==2,_)

184 rows × 12 columns (omitted printing of 8 columns)

IdSurvivedClassName
Int64Int64Int64String
11012Nasser, Mrs. Nicholas (Adele Achem)
21612Hewlett, Mrs. (Mary D Kingcome)
31812Williams, Mr. Charles Eugene
42102Fynney, Mr. Joseph J
52212Beesley, Mr. Lawrence
63402Wheadon, Mr. Edward H
74202Turpin, Mrs. William John Robert (Dorothy Ann Wonnacott)
84412Laroche, Miss. Simonne Marie Anne Andree
95412Faunthorpe, Mrs. Lizzie (Elizabeth Anne Wilkinson)
105712Rugg, Miss. Emily
115912West, Miss. Constance Mirium
126712Nye, Mrs. (Elizabeth Ramell)
137102Jenkin, Mr. Stephen Curnow
147302Hood, Mr. Ambrose Jr
157912Caldwell, Master. Alden Gates
168512Ilett, Miss. Bertha
179912Doling, Mrs. John T (Ada Julia Bone)
1810002Kantor, Mr. Sinai
1911802Turpin, Mr. William John Robert
2012102Hickman, Mr. Stanley George
2112302Nasser, Mr. Nicholas
2212412Webber, Miss. Susan
2313412Weisz, Mrs. Leopold (Mathilde Francoise Pede)
2413502Sobey, Mr. Samuel James Hayden
2513602Richard, Mr. Emile
2614502Andrew, Mr. Edgardo Samuel
2714602Nicholls, Mr. Joseph Charles
2814902Navratil, Mr. Michel ("Louis M Hoffman")
2915002Byles, Rev. Thomas Roussel Davids
3015102Bateman, Rev. Robert James

De igual manera, el paquete Queryverse proporciona la macro @filter para realizar el filtrado, como se muestra a continuación.

dftrain |> @filter _.Class==2
IdSurvivedClassNameGenderAgeSibSpParchTicketFareCabinEmbarked
1012"Nasser, Mrs. Nicholas (Adele Achem)""female"14.010"237736"30.0708"""C"
1612"Hewlett, Mrs. (Mary D Kingcome) ""female"55.000"248706"16.0"""S"
1812"Williams, Mr. Charles Eugene""male"#NA00"244373"13.0"""S"
2102"Fynney, Mr. Joseph J""male"35.000"239865"26.0"""S"
2212"Beesley, Mr. Lawrence""male"34.000"248698"13.0"D56""S"
3402"Wheadon, Mr. Edward H""male"66.000"C.A. 24579"10.5"""S"
4202"Turpin, Mrs. William John Robert (Dorothy Ann Wonnacott)""female"27.010"11668"21.0"""S"
4412"Laroche, Miss. Simonne Marie Anne Andree""female"3.012"SC/Paris 2123"41.5792"""C"
5412"Faunthorpe, Mrs. Lizzie (Elizabeth Anne Wilkinson)""female"29.010"2926"26.0"""S"
5712"Rugg, Miss. Emily""female"21.000"C.A. 31026"10.5"""S"

... with more rows.

Para la primera coincidencia se puede usar la función findfirst

@pipe dftrain |> findfirst(x->x==2,_.Class) |> dftrain[_,:]

DataFrameRow (12 columns)

IdSurvivedClassNameGenderAgeSibSp
Int64Int64Int64StringStringFloat64?Int64
101012Nasser, Mrs. Nicholas (Adele Achem)female14.01

Funciones del paquete

first(dftrain,6);
last(dftrain,6);

Funciones útiles

El paquete DataFrames dispone de varias funciones que pueden ser de utilidad cuando se manipula y se transforman datos. A continuación se mencionan algunos de ellos.

@pipe dftrain |> colwise(sum,_[[:Survived,:Class]])
2-element Array{Int64,1}:
  342
 2057

La función colwise realiza operaciones por columnas cuando es necesario, en este caso el ejemplo no traduce a algo útil, pero ilustra el uso de la función.

Para columnas que no son numéricas puede usarse la función countmap, que cuenta el número de veces que aparece un determinado elemento en la serie (columna) de datos. Para el uso se instala y se importa el paquete StatsBase.

Pkg.add("StatsBase"); using StatsBase
  Resolving package versions...
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Manifest.toml`
@pipe dftrain |> countmap(_[:Gender])
Dict{String,Int64} with 2 entries:
  "male"   => 577
  "female" => 314
@pipe dftrain |> countmap(_[:Embarked ])
Dict{String,Int64} with 4 entries:
  "Q" => 77
  "S" => 644
  "C" => 168
  ""  => 2

Otra función interesante es unique, que devuelve un array con los valores no duplicados.

genders = dftrain[:Gender] |> unique
2-element Array{String,1}:
 "male"
 "female"
dftrain[:TotalFamily] = dftrain.SibSp + dftrain.Parch
891-element Array{Int64,1}:
 1
 1
 0
 1
 0
 0
 0
 4
 2
 1
 2
 0
 0
 ⋮
 1
 1
 0
 0
 0
 0
 5
 0
 0
 3
 0
 0
dftest[:TotalFamily] = dftest.SibSp + dftest.Parch
418-element Array{Float64,1}:
 0.0
 1.0
 0.0
 0.0
 2.0
 0.0
 0.0
 2.0
 0.0
 2.0
 0.0
 0.0
 1.0
 ⋮
 1.0
 2.0
 0.0
 2.0
 0.0
 1.0
 0.0
 0.0
 0.0
 0.0
 0.0
 2.0
dftrain[:new] = dftrain.SibSp + dftrain.Parch; 
dftrain

891 rows × 14 columns (omitted printing of 10 columns)

IdSurvivedClassName
Int64Int64Int64String
1103Braund, Mr. Owen Harris
2211Cumings, Mrs. John Bradley (Florence Briggs Thayer)
3313Heikkinen, Miss. Laina
4411Futrelle, Mrs. Jacques Heath (Lily May Peel)
5503Allen, Mr. William Henry
6603Moran, Mr. James
7701McCarthy, Mr. Timothy J
8803Palsson, Master. Gosta Leonard
9913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)
101012Nasser, Mrs. Nicholas (Adele Achem)
111113Sandstrom, Miss. Marguerite Rut
121211Bonnell, Miss. Elizabeth
131303Saundercock, Mr. William Henry
141403Andersson, Mr. Anders Johan
151503Vestrom, Miss. Hulda Amanda Adolfina
161612Hewlett, Mrs. (Mary D Kingcome)
171703Rice, Master. Eugene
181812Williams, Mr. Charles Eugene
191903Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)
202013Masselmani, Mrs. Fatima
212102Fynney, Mr. Joseph J
222212Beesley, Mr. Lawrence
232313McGowan, Miss. Anna "Annie"
242411Sloper, Mr. William Thompson
252503Palsson, Miss. Torborg Danira
262613Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)
272703Emir, Mr. Farred Chehab
282801Fortune, Mr. Charles Alexander
292913O'Dwyer, Miss. Ellen "Nellie"
303003Todoroff, Mr. Lalio

En el ejemplo anterior una columna, con el nombre TotalFamily, fue añadida al dataframe. Una columna adicional es agregado, new, para ilustrar cómo se elimina.

select!(dftrain,Not([:new]))

891 rows × 13 columns (omitted printing of 9 columns)

IdSurvivedClassName
Int64Int64Int64String
1103Braund, Mr. Owen Harris
2211Cumings, Mrs. John Bradley (Florence Briggs Thayer)
3313Heikkinen, Miss. Laina
4411Futrelle, Mrs. Jacques Heath (Lily May Peel)
5503Allen, Mr. William Henry
6603Moran, Mr. James
7701McCarthy, Mr. Timothy J
8803Palsson, Master. Gosta Leonard
9913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)
101012Nasser, Mrs. Nicholas (Adele Achem)
111113Sandstrom, Miss. Marguerite Rut
121211Bonnell, Miss. Elizabeth
131303Saundercock, Mr. William Henry
141403Andersson, Mr. Anders Johan
151503Vestrom, Miss. Hulda Amanda Adolfina
161612Hewlett, Mrs. (Mary D Kingcome)
171703Rice, Master. Eugene
181812Williams, Mr. Charles Eugene
191903Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)
202013Masselmani, Mrs. Fatima
212102Fynney, Mr. Joseph J
222212Beesley, Mr. Lawrence
232313McGowan, Miss. Anna "Annie"
242411Sloper, Mr. William Thompson
252503Palsson, Miss. Torborg Danira
262613Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)
272703Emir, Mr. Farred Chehab
282801Fortune, Mr. Charles Alexander
292913O'Dwyer, Miss. Ellen "Nellie"
303003Todoroff, Mr. Lalio

Para eliminar una fila del dataframe se puede usar la función delete! y para añadir una fila se puede usar la función push!. En delete! se indica el dataframe y el índice de la fila que debe ser eliminada.

Existen otro conjunto de funciones que son de utilizada cuando se requiere realizar una consulta compleja en la data, el paquete Queryverse por contener el módulo Query ofrece opciones interesantes que pueden ser consultados en los siguientes enlaces: link₁, lin₂, lin₃.

Más funciones puede ser encontrado en la siguiente introducción al paquete DataFrames.

Manejo de fechas

Es usual que al indagar en los datos y transformarlos se manejen fechas. En Julia ello se realiza con el paquete Dates, el cual nos permite dar formato a las fechas y realizar operaciones con ellas.

Para construir un objeto tipo fecha se pueden usar los constructores Date y DateTime, los cuales diferen en la precisión (día y milisegundos respectivamente).

Pkg.add("Dates"); using Dates
  Resolving package versions...
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Manifest.toml`
Date(2021), Date(2021,5), Date(2021,6,4)
(Date("2021-01-01"), Date("2021-05-01"), Date("2021-06-04"))
DateTime(2021), DateTime(2021,5), DateTime(2021,6,4)
(DateTime("2021-01-01T00:00:00"), DateTime("2021-05-01T00:00:00"), DateTime("2021-06-04T00:00:00"))

En algunas ocasiones se encontrará necesario dar formato a una cadena de caracteres que representan una fecha, para ello en los constructores se especifica el formato de la cadena de texto, en el cual existen diferentes opciones.

Date("2021-3","yyyy-m"), Date("2021/08/9","yy/mm/d"), Date("20210809","yyyymmdd"), Date("21-3","yyyy-m")
(Date("2021-03-01"), Date("2021-08-09"), Date("2021-08-09"), Date("0021-03-01"))

Si existen muchos datos de fecha a formatear y tienen un formato similar, es más eficiente crear el formato primero y luego usarlo en el constructor, por ejemplo: dateformat=DateFormat(\"dd/mm/yyyy\").

En los ejemplos se puede notar que exite un error para la última fecha, cuando ocurre esas situaciones se debe parsear la cadena de texto para ser convertido a una cadena tipo fecha.

parse(Dates.Date,"2021-3",Dates.DateFormat("yyyy-m"))
2021-03-01

Para conocer más sobre el manejo de fechas revisar esta documentación. md

Respondiendo interrogantes y visualización de datos

Para ilustrar cómo se utilizan algunas de las funciones más avanzadas, mencionadas hacia el final de la sección “Funciones útiles”, podemos dar respuesta a las siguientes preguntas:

  • ¿Cuántas personas iban en el titanic?

  • ¿Cuántos hombres y mujeres sobrevivieron?

  • ¿Cuál fué el top 10 de edad que más sobrevivieron?

  • ¿Cuál fue el top 10 de edad que no lograron sobrevivir?

El paquete StatPlots ofrece una macro @df, el cual se usa junto con Plots para graficar datos de dataframe.

Pkg.add("StatsPlots"); using StatsPlots
  Resolving package versions...
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Manifest.toml`

A continuación una rutina para responder la primera interrogante.

begin ###Preparamos los datos para unir los dataframes
	survivedtest = @pipe load("./titanic/gender_submission.csv") |> 
					DataFrame |> 
					rename!(_,:PassengerId=>"Id") |>
					Float64.(_)
	dftest₁ = @from i in dftest begin
			  @join j in survivedtest on i.Id equals j.Id
			  @select {i.Id, j.Survived, i.Class,i.Name, i.Gender, i.Age, i.SibSp, i.Parch, i.Ticket, i.Fare, i.Cabin, i.Embarked, i.TotalFamily}
			  @collect DataFrame
	end
end;
df = vcat(dftrain[:,:], dftest₁[:,:]); ###Se deben unir los dataframes
describe(df);

¿Cuántas personas iban en el titanic?

length(df[:Id])
1309

¿Cuántos hombres y mujeres sobrevivieron?

genders
2-element Array{String,1}:
 "male"
 "female"
👨 = df |> @filter(_.Gender=="male" && _.Survived==1) |> collect |> length
109
👩 = df |> @filter(_.Gender=="female" && _.Survived==1) |> collect |> length
385

¿Cuál fué el top 10 de edad que más sobrevivieron?

agesurviver = df[df.Survived.==1, [:Age]] |> 
				dropmissing |> 
				@groupby(_[:Age]) |>
				@map({Edadesₛ=key(_), Countₛ=length(_)}) |>
				DataFrame;
agesurviver

71 rows × 2 columns

EdadesₛCountₛ
Float64Int64
138.07
226.010
335.014
427.015
514.03
64.07
758.04
855.04
934.06
1015.05
1128.09
123.06
1319.012
1449.04
1529.013
1621.08
175.04
1817.08
1932.09
200.832
2130.016
2233.09
2323.010
2432.51
2512.03
2624.020
2722.021
2816.08
2940.06
309.03
@pipe sort!(agesurviver,[:Countₛ],rev=true) |> first(_,10)

10 rows × 2 columns

EdadesₛCountₛ
Float64Int64
122.021
224.020
330.016
418.016
536.016
627.015
735.014
829.013
919.012
1045.012
@pipe df[df.Survived.==1, [:Age]] |> 
		dropmissing |> 
		groupby(_,:Age)  |> 
		combine(_,:Age=>length=>:Countₛ) |> 
		sort(_,[:Countₛ],rev=true) |> 
		first(_,10)

10 rows × 2 columns

AgeCountₛ
Float64Int64
122.021
224.020
330.016
418.016
536.016
627.015
735.014
829.013
919.012
1045.012

¿Cuál fue el top 10 de edad que no lograron sobrevivir?

notagesurviver = df[df.Survived.==0, [:Age]] |> 
	  			 dropmissing |> 
				 @groupby(_[:Age]) |>
				 @map({Edadesₙₛ=key(_), Countₙₛ=length(_)}) |>
				 DataFrame;
@pipe sort!(notagesurviver,[:Countₙₛ],rev=true) |> first(_,10)

10 rows × 2 columns

EdadesₙₛCountₙₛ
Float64Int64
121.033
225.027
324.027
430.024
528.023
618.023
722.022
826.020
919.017
1029.017
@pipe df[df.Survived.==0, [:Age]] |> 
		dropmissing |> 
		groupby(_,:Age)  |> 
		combine(_,:Age=>length=>:Countₛ) |> 
		sort(_,[:Countₛ],rev=true) |> 
		first(_,10)

10 rows × 2 columns

AgeCountₛ
Float64Int64
121.033
225.027
324.027
430.024
528.023
618.023
722.022
826.020
919.017
1029.017

Gráfica con Plots

dfplotₛ = DataFrame();
dfplotₛ[:Gender] = @pipe df[df.Survived.==1, [:Gender]] |> 
			map(x->x=="male" ? 0 : 1, _[:Gender])
494-element Array{Int64,1}:
 1
 1
 1
 1
 1
 1
 1
 1
 0
 1
 0
 1
 0
 ⋮
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
dfplotₙₛ = DataFrame();
dfplotₙₛ[:Gender] = @pipe df[df.Survived.==0, [:Gender]] |> 
			map(x->x=="male" ? 0 : 1, _[:Gender])
815-element Array{Int64,1}:
 0
 0
 0
 0
 0
 0
 0
 1
 0
 1
 0
 1
 0
 ⋮
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
@df dfplotₛ plot(:Gender, seriestype=:histogram, legend=:none, bar_width=0.9, xticks=([0.15,1.15],["Varón", "Mujer"]), title="Sobrevivientes")
_images/Paquete_DataFrames_113_0.svg
@df dfplotₙₛ plot(:Gender, seriestype=:histogram, legend=:none, bar_width=0.9, xticks=([0.15,1.15],["Varón", "Mujer"]), title="No Sobrevivientes")
_images/Paquete_DataFrames_114_0.svg
f = DataFrame(a = 1:10, b = 10 * rand(10), c = 10 * rand(10));
@df f plot(:a, [:b :c])
_images/Paquete_DataFrames_116_0.svg

Paquete PlutoUI

Este paquete es que agrega syntactic sugar para alguna de las funcionalidades de Pluto. PlutoUI puede ser implementado para colocar widgets en el cuaderno y hacer más interactivo el programa que se escriba.

Pkg.add("PlutoUI"); using PlutoUI;
  Resolving package versions...
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Project.toml`
No Changes to `~/work/Intro-Julia-2021/Intro-Julia-2021/Manifest.toml`
@bind gender Select(genders) 
LoadError: UndefVarError: @bind not defined
in expression starting at In[75]:1

Stacktrace:
 [1] top-level scope
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091
@bind number Slider(1:9) 
LoadError: UndefVarError: @bind not defined
in expression starting at In[76]:1

Stacktrace:
 [1] top-level scope
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091
gender, number
UndefVarError: gender not defined

Stacktrace:
 [1] top-level scope at In[77]:1
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091

Utilidades de Queryverse

datatrain |> @vlplot(:point,x=:Survived,y=:Pclass,color="Sex:n")
Unable to revert mtime: /usr/share/fonts
Unable to revert mtime: /usr/share/fonts/cMap
Unable to revert mtime: /usr/share/fonts/cmap
Unable to revert mtime: /usr/share/fonts/truetype
Unable to revert mtime: /usr/share/fonts/type1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-cns1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-gb1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-japan1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-japan2
Unable to revert mtime: /usr/share/fonts/cmap/adobe-korea1
Unable to revert mtime: /usr/share/fonts/truetype/dejavu
Unable to revert mtime: /usr/share/fonts/truetype/droid
Unable to revert mtime: /usr/share/fonts/truetype/lato
Unable to revert mtime: /usr/share/fonts/truetype/liberation
Unable to revert mtime: /usr/share/fonts/truetype/noto
Unable to revert mtime: /usr/share/fonts/type1/gsfonts
Unable to revert mtime: /usr/share/fonts/cMap
Unable to revert mtime: /usr/share/fonts/cmap/adobe-cns1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-gb1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-japan1
Unable to revert mtime: /usr/share/fonts/cmap/adobe-japan2
Unable to revert mtime: /usr/share/fonts/cmap/adobe-korea1
_images/Paquete_DataFrames_123_4.svg

Es posible realizar una gráfica como se muestra en el ejemplo, donde no se usa Plots.jl.

datatrain |> Voyager
(electron:7624): Gtk-WARNING **: 18:57:11.426: cannot open display: 

Voyager es una utilidad que permite explorar de forma rápida los gráficos, ofreciendo la posibilidad de visualizarlos con gráficos.