
Julia es uno de los lenguajes de programación matemáticos más jóvenes y afirma ser el principal lenguaje de programación en esta área. Desafortunadamente, por el momento no hay suficiente literatura en ruso, y los materiales disponibles en inglés contienen información que, debido al desarrollo dinámico de Julia, no siempre corresponde a la versión actual, pero esto no es obvio para los programadores principiantes de Julia. Intentaremos llenar los vacíos y transmitir las ideas de Julia a los lectores en forma de ejemplos simples.
El propósito de este artículo es dar a los lectores una idea de las formas básicas de trabajar con tablas en el lenguaje de programación Julia para alentarlos a comenzar a usar este lenguaje de programación para procesar datos reales. Suponemos que el lector ya está familiarizado con otros lenguajes de programación, por lo que daremos solo información mínima sobre cómo se hace esto, pero no entraremos en detalles sobre los métodos de procesamiento de datos.
Por supuesto, una de las etapas más importantes en el trabajo de un programa que realiza análisis de datos es su importación y exportación. Además, el formato de presentación de datos más común es una tabla. Hay bibliotecas para Julia que proporcionan acceso a DBMS relacionales, usan formatos de intercambio como HDF5, MATLAB, JLD. Pero en este caso, solo nos interesará el formato de texto para representar tablas, como CSV.
Antes de mirar las tablas, debe hacer una pequeña introducción a la presentación de esta estructura de datos. Para Julia, una tabla se puede representar como una matriz bidimensional o como un DataFrame.
Matrices
Comencemos con las matrices en Julia. La numeración de elementos comienza con uno. Esto es bastante natural para los matemáticos, y además, el mismo esquema se usa en Fortran, Pascal, Matlab. Para los programadores que nunca han usado estos lenguajes, esta numeración puede parecer incómoda y causar errores al escribir condiciones límite, pero, en realidad, esto es solo una cuestión de hábito. Después de un par de semanas de usar Julia, ya no surge la cuestión de cambiar entre modelos de idiomas.
El segundo punto significativo de este lenguaje es la representación interna de las matrices. Para Julia, una matriz lineal es una columna. Al mismo tiempo, para lenguajes como C, Java, una matriz unidimensional es una cadena.
Ilustramos esto con una matriz creada en la línea de comando (REPL)
julia> a = [1, 2, 3] 3-element Array{Int64,1}: 1 2 3
Preste atención al tipo de matriz: matriz {Int64,1}. La matriz es unidimensional, escriba Int64. Además, si queremos combinar esta matriz con otra matriz, entonces, dado que estamos tratando con una columna, debemos usar la función vcat (es decir, concatenación vertical). El resultado es una nueva columna.
julia> b = vcat(a, [5, 6, 7]) 7-element Array{Int64,1}: 1 2 3 5 6 7
Si creamos una matriz como una cadena, cuando escribimos un literal, usamos espacios en lugar de comas y obtenemos una matriz bidimensional de tipo Array {Int64,2}. El segundo argumento en la declaración de tipo significa el número de coordenadas de la matriz multidimensional.
julia> c = [1 2 3] 1×3 Array{Int64,2}: 1 2 3
Es decir, tenemos una matriz con una fila y tres columnas.
Esta presentación de filas y columnas también es característica de Fortran y Matlab, pero solo debe recordarse que Julia es un lenguaje orientado específicamente a su campo de aplicación.
La matriz para Julia es una matriz bidimensional, donde todas las celdas son del mismo tipo. Prestemos atención al hecho de que el tipo puede ser abstracto Cualquiera o bastante específico, como Int64, Float64 o, incluso, String.
Podemos crear una matriz en forma de literal:
julia> a = [1 2; 3 4] 2×2 Array{Int64,2}: 1 2 3 4
Cree usando el constructor y asigne memoria sin inicialización (undef):
julia> a = Array{Int64,2}(undef, 2, 3) 2×3 Array{Int64,2}: 4783881648 4783881712 4782818640 4783881680 4783881744 4782818576
O con inicialización si se especifica algún valor específico en lugar de undef.
Pegamento de columnas separadas:
julia> a = [1, 2, 3] 3-element Array{Int64,1}: 1 2 3 julia> b = hcat(a, a, a, a) 3×4 Array{Int64,2}: 1 1 1 1 2 2 2 2 3 3 3 3
Inicializar al azar:
julia> x = rand(1:10, 2, 3) 2×3 Array{Int64,2}: 1 10 2 9 7 7
Argumentos rand: rango de 1 a 10 y dimensión 2 x 3.
O use la inclusión (Comprensiones)
julia> x = [min(i, j) for i = 0:2, j = 0:2 ] 3×3 Array{Int64,2}: 0 0 0 0 1 1 0 1 2
Tenga en cuenta que el hecho de que las columnas de Julia sean un bloque lineal de memoria lleva al hecho de que iterar sobre los elementos por columna será significativamente más rápido que ordenar las filas. En particular, el siguiente ejemplo utiliza una matriz de 1_000_000 filas y 100 columnas.
#!/usr/bin/env julia using BenchmarkTools x = rand(1:1000, 1_000_000, 100) #x = rand(1_000_000, 100) function sumbycolumns(x) sum = 0 rows, cols = size(x) for j = 1:cols, i = 1:rows sum += x[i, j] end return sum end @show @btime sumbycolumns(x) function sumbyrows(x) sum = 0 rows, cols = size(x) for i = 1:rows, j = 1:cols sum += x[i, j] end return sum end @show @btime sumbyrows(x)
Resultados:
74.378 ms (1 allocation: 16 bytes) =# @btime(sumbycolumns(x)) = 50053093495 206.346 ms (1 allocation: 16 bytes) =# @btime(sumbyrows(x)) = 50053093495
@btime en el ejemplo es una ejecución múltiple de una función para calcular el tiempo promedio que se tarda en ejecutar. Esta macro es proporcionada por la biblioteca BenchmarkTools.jl. El kit base de Julia tiene una macro de tiempo , pero mide un solo intervalo, que, en este caso, será inexacto. La macro show simplemente muestra la expresión y su valor calculado en la consola.
La optimización del almacenamiento de columnas es conveniente para realizar operaciones estadísticas con una tabla. Como tradicionalmente, la tabla está limitada por el número de columnas, y el número de filas puede ser cualquiera, la mayoría de las operaciones, como el cálculo de los valores promedio, mínimo y máximo, se realizan específicamente para las columnas de las matrices y no para sus filas.
Un sinónimo de una matriz bidimensional es el tipo Matrix. Sin embargo, esto es más una conveniencia de estilo que una necesidad.
El acceso a los elementos de la matriz se realiza por índice. Por ejemplo, para una matriz creada previamente
julia> x = rand(1:10, 2, 3) 2×3 Array{Int64,2}: 1 10 2 9 7 7
Podemos obtener un elemento específico como x [1, 2] => 10. Entonces obtenga la columna completa, por ejemplo, la segunda columna:
julia> x[:, 2] 2-element Array{Int64,1}: 10 7
O la segunda línea:
julia> x[2, :] 3-element Array{Int64,1}: 9 7 7
También hay una función selectdim útil, donde puede especificar el número ordinal de la dimensión para la que desea realizar una selección, así como los índices de los elementos de esta dimensión. Por ejemplo, realice un muestreo en la segunda dimensión (columnas) seleccionando los índices primero y tercero. Este enfoque es conveniente cuando, según las condiciones, necesita cambiar entre filas y columnas. Sin embargo, esto es cierto para el caso multidimensional, cuando el número de dimensiones es superior a 2.
julia> selectdim(x, 2, [1, 3]) 2×2 view(::Array{Int64,2}, :, [1, 3]) with eltype Int64: 1 2 9 7
Funciones para el procesamiento estadístico de matrices.
Más sobre matrices unidimensionales
Matrices Multidimensionales
Funciones de álgebra lineal y matrices de una forma especial.
La lectura de una tabla desde un archivo se puede hacer usando la función readdlm implementada en la biblioteca DelimitedFiles. Grabación - usando writedlm. Estas funciones proporcionan trabajo con archivos con delimitadores, un caso especial de los cuales es el formato CSV.
Ilustramos con un ejemplo de la documentación:
julia> using DelimitedFiles julia> x = [1; 2; 3; 4]; julia> y = ["a"; "b"; "c"; "d"]; julia> open("delim_file.txt", "w") do io writedlm(io, [xy]) # end; julia> readdlm("delim_file.txt") # 4×2 Array{Any,2}: 1 "a" 2 "b" 3 "c" 4 "d"
En este caso, debe prestar atención al hecho de que la tabla contiene datos de diferentes tipos. Por lo tanto, al leer un archivo, se crea una matriz de tipo Array {Any, 2}.
Otro ejemplo es leer tablas que contienen datos homogéneos.
julia> using DelimitedFiles julia> x = [1; 2; 3; 4]; julia> y = [5; 6; 7; 8]; julia> open("delim_file.txt", "w") do io writedlm(io, [xy]) # end; julia> readdlm("delim_file.txt", Int64) # Int64 4×2 Array{Int64,2}: 1 5 2 6 3 7 4 8 julia> readdlm("delim_file.txt", Float64) # Float64 4×2 Array{Float64,2}: 1.0 5.0 2.0 6.0 3.0 7.0 4.0 8.0
Desde el punto de vista de la eficiencia del procesamiento, esta opción es preferible, ya que los datos se presentarán de forma compacta. Al mismo tiempo, una restricción explícita en las tablas representadas por la matriz es un requisito para la uniformidad de los datos.
Recomendamos ver las características completas de readdlm en la documentación. Entre las opciones adicionales está la capacidad de especificar el modo de procesamiento de los encabezados, las líneas de salto, la función de procesamiento de celdas, etc.
Una forma alternativa de leer tablas es la biblioteca CSV.jl. En comparación con readdlm y writedlm, esta biblioteca proporciona un control significativamente mayor sobre las opciones de escritura y lectura, así como la verificación de datos en archivos delimitados. Sin embargo, la diferencia fundamental es que el resultado de la función CSV.File se puede materializar en el tipo DataFrame.
Marcos de datos
La biblioteca DataFrames proporciona soporte para la estructura de datos DataFrame, que se centra en la presentación de tablas. La diferencia fundamental de la matriz aquí es que cada columna se almacena individualmente y cada columna tiene su propio nombre. Recordamos que para Julia, el modo de almacenamiento en columnas, en general, es natural. Y, aunque aquí tenemos un caso especial de matrices unidimensionales, se obtiene una solución óptima tanto en términos de velocidad como de flexibilidad de representación de datos, ya que el tipo de cada columna puede ser individual.
Veamos cómo crear un DataFrame.
Cualquier matriz se puede convertir en un DataFrame.
julia> using DataFrames julia> a = [1 2; 3 4; 5 6] 3×2 Array{Int64,2}: 1 2 3 4 5 6 julia> b = convert(DataFrame, a) 3×2 DataFrame │ Row │ x1 │ x2 │ │ │ Int64 │ Int64 │ ├─────┼───────┼───────┤ │ 1 │ 1 │ 2 │ │ 2 │ 3 │ 4 │ │ 3 │ 5 │ 6 │
La función de conversión convierte los datos al tipo especificado. En consecuencia, para el tipo DataFrame, los métodos de la función de conversión se definen en la biblioteca DataFrames (según la terminología de Julia, hay funciones y la variedad de sus implementaciones con diferentes argumentos se denominan métodos). Cabe señalar que a las columnas de la matriz se les asignan automáticamente los nombres x1, x2. Es decir, si ahora solicitamos nombres de columna, los obtendremos en forma de matriz:
julia> names(b) 2-element Array{Symbol,1}: :x1 :x2
Y los nombres se presentan en un formato como Symbol (conocido en el mundo Ruby).
Se puede crear un DataFrame directamente, vacío o que contenga algunos datos en el momento de la construcción. Por ejemplo:
julia> df = DataFrame([collect(1:3), collect(4:6)], [:A, :B]) 3×2 DataFrame │ Row │ A │ B │ │ │ Int64 │ Int64 │ ├─────┼───────┼───────┤ │ 1 │ 1 │ 4 │ │ 2 │ 2 │ 5 │ │ 3 │ 3 │ 6 │
Aquí indicamos una matriz con valores de columna y una matriz con los nombres de estas columnas. Las construcciones de la forma collect (1: 3) son la conversión de un rango de iterador de 1 a 3 en una matriz de valores.
El acceso a las columnas es posible tanto por su nombre como por índice.
Es muy fácil agregar una nueva columna escribiendo algún valor en todas las filas existentes. Por ejemplo, df arriba, queremos agregar la columna Puntaje. Para hacer esto, necesitamos escribir:
julia> df[:Score] = 0.0 0.0 julia> df 3×3 DataFrame │ Row │ A │ B │ Score │ │ │ Int64 │ Int64 │ Float64 │ ├─────┼───────┼───────┼─────────┤ │ 1 │ 1 │ 4 │ 0.0 │ │ 2 │ 2 │ 5 │ 0.0 │ │ 3 │ 3 │ 6 │ 0.0 │
Así como en el caso de matrices simples, podemos pegar instancias de DataFrame usando las funciones vcat, hcat. Sin embargo, vcat solo se puede usar con las mismas columnas en ambas tablas. Puede alinear un DataFrame, por ejemplo, utilizando la siguiente función:
function merge_df(first::DataFrame, second::DataFrame)::DataFrame if (first == nothing) return second else names_first = names(first) names_second = names(second) sub_names = setdiff(names_first, names_second) second[sub_names] = 0 sub_names = setdiff(names_second, names_first) first[sub_names] = 0 vcat(second, first) end end
La función de nombres aquí obtiene una matriz de nombres de columna. La función setdiff (s1, s2) en el ejemplo detecta todos los elementos de s1 que no están en s2. A continuación, expanda el DataFrame a estos elementos. vcat pega dos DataFrames y devuelve el resultado. No es necesario utilizar return en este caso, ya que el resultado de la última operación es obvio.
Podemos verificar el resultado:
julia> df1 = DataFrame(:A => collect(1:2)) 2×1 DataFrame │ Row │ A │ │ │ Int64 │ ├─────┼───────┤ │ 1 │ 1 │ │ 2 │ 2 │ julia> df2 = DataFrame(:B => collect(3:4)) 2×1 DataFrame │ Row │ B │ │ │ Int64 │ ├─────┼───────┤ │ 1 │ 3 │ │ 2 │ 4 │ julia> df3 = merge_df(df1, df2) 4×2 DataFrame │ Row │ B │ A │ │ │ Int64 │ Int64 │ ├─────┼───────┼───────┤ │ 1 │ 3 │ 0 │ │ 2 │ 4 │ 0 │ │ 3 │ 0 │ 1 │ │ 4 │ 0 │ 2 │
Tenga en cuenta que, en términos de convenciones de nomenclatura en Julia, no es habitual utilizar guiones bajos, pero la legibilidad se ve afectada. Tampoco es bastante bueno en esta implementación es que se modifique el DataFrame original. Pero, sin embargo, este ejemplo es bueno para ilustrar el proceso de alinear múltiples columnas.
Es posible unir varios DataFrames mediante valores comunes en columnas mediante la función de unión (por ejemplo, pegar dos tablas con columnas diferentes mediante identificadores de usuarios comunes).
DataFrame es conveniente para ver en la consola. Cualquier forma de salida: usando la macro show , usando la función println, etc., se imprimirá una tabla en la consola en una forma fácil de leer. Si el DataFrame es demasiado grande, se mostrarán las líneas de inicio y fin. Sin embargo, puede solicitar explícitamente la cabeza y la cola con las funciones de cabeza y cola, respectivamente.
Para DataFrame, las funciones de agrupación y agregación de datos para la función especificada están disponibles. Hay diferencias en lo que devuelven. Esto puede ser una colección con un DataFrame que cumple con los criterios de agrupación, o un solo DataFrame donde los nombres de columna se formarán a partir del nombre original y el nombre de la función de agregación. En esencia, se implementa un esquema de división-aplicación-combinación. Ver detalles
Utilizaremos un ejemplo de la documentación con una tabla de ejemplo disponible como parte del paquete DataFrames.
julia> using DataFrames, CSV, Statistics julia> iris = CSV.read(joinpath(dirname(pathof(DataFrames)), "../test/data/iris.csv"));
Realice la agrupación utilizando la función groupby. Especifique el nombre de la columna de agrupación y obtenga un resultado del tipo GroupedDataFrame, que contiene una colección de marcos de datos individuales recopilados por los valores de la columna de agrupación.
julia> species = groupby(iris, :Species) GroupedDataFrame with 3 groups based on key: :Species First Group: 50 rows │ Row │ SepalLength │ SepalWidth │ PetalLength │ PetalWidth │ Species │ │ │ Float64 │ Float64 │ Float64 │ Float64 │ String │ ├─────┼─────────────┼────────────┼─────────────┼────────────┼─────────┤ │ 1 │ 5.1 │ 3.5 │ 1.4 │ 0.2 │ setosa │ │ 2 │ 4.9 │ 3.0 │ 1.4 │ 0.2 │ setosa │ │ 3 │ 4.7 │ 3.2 │ 1.3 │ 0.2 │ setosa │
El resultado se puede convertir a una matriz utilizando la función de recopilación mencionada anteriormente:
julia> collect(species) 3-element Array{Any,1}: 50×5 SubDataFrame{Array{Int64,1}} │ Row │ SepalLength │ SepalWidth │ PetalLength │ PetalWidth │ Species │ │ │ Float64 │ Float64 │ Float64 │ Float64 │ String │ ├─────┼─────────────┼────────────┼─────────────┼────────────┼─────────┤ │ 1 │ 5.1 │ 3.5 │ 1.4 │ 0.2 │ setosa │ │ 2 │ 4.9 │ 3.0 │ 1.4 │ 0.2 │ setosa │ │ 3 │ 4.7 │ 3.2 │ 1.3 │ 0.2 │ setosa │ …
Agrupe utilizando la función by. Especifique el nombre de la columna y la función de procesamiento del DataFrame recibido. La primera etapa de trabajo es similar a la función groupby: obtenemos la colección DataFrame. Para cada uno de estos DataFrame, cuente el número de filas y colóquelas en la columna N. El resultado se pegará en un solo DataFrame y se devolverá como resultado de la función by.
julia> by(iris, :Species, df -> DataFrame(N = size(df, 1))) 3×2 DataFrame │ Row │ Species │ N │ │ │ String⍰ │ Int64 │ ├─────┼────────────┼───────┤ │ 1 │ setosa │ 50 │ │ 2 │ versicolor │ 50 │ │ 3 │ virginica │ 50 │
Bueno, la última opción es la función agregada. Especificamos una columna para agrupar y una función de agregación para las columnas restantes. El resultado es un DataFrame donde se formarán los nombres de las columnas en nombre de las columnas de origen y el nombre de la función de agregación.
julia> aggregate(iris, :Species, sum) 3×5 DataFrame │Row│Species │SepalLength_sum│SepalWidth_sum│PetalLength_sum│PetalWidth_sum│ │ │ String │ Float64 │ Float64 │ Float64 │ Float64 │ ├───┼──────────┼───────────────┼──────────────┼───────────────┼──────────────┤ │ 1 │setosa │250.3 │ 171.4 │ 73.1 │ 12.3 │ │ 2 │versicolor│296.8 │ 138.5 │ 213.0 │ 66.3 │ │ 3 │virginica │329.4 │ 148.7 │ 277.6 │ 101.3 │
La función colwise aplica la función especificada a todas o solo las columnas DataFrame especificadas.
julia> colwise(mean, iris[1:4]) 4-element Array{Float64,1}: 5.843333333333335 3.057333333333334 3.7580000000000027 1.199333333333334
Se describe una función muy conveniente para obtener un resumen de la tabla. Ejemplo de uso:
julia> describe(iris) 5×8 DataFrame │Row│ variable │mean │min │median│ max │nunique│nmissing│ eltype │ │ │ Symbol │Union… │Any │Union…│ Any │Union… │Int64 │DataType│ ├───┼───────────┼───────┼──────┼──────┼─────────┼───────┼────────┼────────┤ │ 1 │SepalLength│5.84333│ 4.3 │ 5.8 │ 7.9 │ │ 0 │ Float64│ │ 2 │SepalWidth │3.05733│ 2.0 │ 3.0 │ 4.4 │ │ 0 │ Float64│ │ 3 │PetalLength│3.758 │ 1.0 │ 4.35 │ 6.9 │ │ 0 │ Float64│ │ 4 │PetalWidth │1.19933│ 0.1 │ 1.3 │ 2.5 │ │ 0 │ Float64│ │ 5 │Species │ │setosa│ │virginica│ 3 │ 0 │ String │
Lista completa de características de DataFrames .
Al igual que con el caso de Matrix, puede usar todas las funciones estadísticas disponibles en el módulo Estadísticas en el Marco de datos. Ver https://docs.julialang.org/en/v1/stdlib/Statistics/index.html
La biblioteca StatPlots.jl se usa para mostrar gráficamente el DataFrame. Ver más https://github.com/JuliaPlots/StatPlots.jl
Esta biblioteca implementa un conjunto de macros para simplificar la visualización.
julia> df = DataFrame(a = 1:10, b = 10 .* rand(10), c = 10 .* rand(10)) 10×3 DataFrame │ Row │ a │ b │ c │ │ │ Int64 │ Float64 │ Float64 │ ├─────┼───────┼─────────┼─────────┤ │ 1 │ 1 │ 0.73614 │ 7.11238 │ │ 2 │ 2 │ 5.5223 │ 1.42414 │ │ 3 │ 3 │ 3.5004 │ 2.11633 │ │ 4 │ 4 │ 1.34176 │ 7.54208 │ │ 5 │ 5 │ 8.52392 │ 2.98558 │ │ 6 │ 6 │ 4.47477 │ 6.36836 │ │ 7 │ 7 │ 8.48093 │ 6.59236 │ │ 8 │ 8 │ 5.3761 │ 2.5127 │ │ 9 │ 9 │ 3.55393 │ 9.2782 │ │ 10 │ 10 │ 3.50925 │ 7.07576 │ julia> @df df plot(:a, [:b :c], colour = [:red :blue])

En la última línea, @df es la macro, df es el nombre de la variable con el DataFrame.
Query.jl puede ser una biblioteca muy útil. Utilizando los mecanismos de macros y el canal de procesamiento, Query.jl proporciona un lenguaje de consulta especializado. Un ejemplo es obtener una lista de personas mayores de 50 años y la cantidad de hijos que tienen:
julia> using Query, DataFrames julia> df = DataFrame(name=["John", "Sally", "Kirk"], age=[23., 42., 59.], children=[3,5,2]) 3×3 DataFrame │ Row │ name │ age │ children │ │ │ String │ Float64 │ Int64 │ ├─────┼────────┼─────────┼──────────┤ │ 1 │ John │ 23.0 │ 3 │ │ 2 │ Sally │ 42.0 │ 5 │ │ 3 │ Kirk │ 59.0 │ 2 │ julia> x = @from i in df begin @where i.age>50 @select {i.name, i.children} @collect DataFrame end 1×2 DataFrame │ Row │ name │ children │ │ │ String │ Int64 │ ├─────┼────────┼──────────┤ │ 1 │ Kirk │ 2 │
O un formulario con un canal:
julia> using Query, DataFrames julia> df = DataFrame(name=["John", "Sally", "Kirk"], age=[23., 42., 59.], children=[3,5,2]); julia> x = df |> @query(i, begin @where i.age>50 @select {i.name, i.children} end) |> DataFrame 1×2 DataFrame │ Row │ name │ children │ │ │ String │ Int64 │ ├─────┼────────┼──────────┤ │ 1 │ Kirk │ 2 │
Ver más detalles
Los dos ejemplos anteriores demuestran el uso de lenguajes de consulta funcionalmente similares a dplyr o LINQ. Además, estos idiomas no se limitan a Query.jl. Obtenga más información sobre el uso de estos idiomas con DataFrames aquí .
El último ejemplo utiliza el operador | |. Ver más
Este operador sustituye el argumento en la función que se indica a la derecha del mismo. En otras palabras:
julia> [1:5;] |> x->x.^2 |> sum |> inv 0.01818181818181818
Equivalente a:
julia> inv(sum( [1:5;] .^ 2 )) 0.01818181818181818
Y lo último que me gustaría señalar es la capacidad de escribir un DataFrame en el formato de salida con un separador utilizando la biblioteca CSV.jl mencionada anteriormente
julia> df = DataFrame(name=["John", "Sally", "Kirk"], age=[23., 42., 59.], children=[3,5,2]) 3×3 DataFrame │ Row │ name │ age │ children │ │ │ String │ Float64 │ Int64 │ ├─────┼────────┼─────────┼──────────┤ │ 1 │ John │ 23.0 │ 3 │ │ 2 │ Sally │ 42.0 │ 5 │ │ 3 │ Kirk │ 59.0 │ 2 │ julia> CSV.write("out.csv", df) "out.csv"
Podemos verificar el resultado registrado:
> cat out.csv name,age,children John,23.0,3 Sally,42.0,5 Kirk,59.0,2
Conclusión
Es difícil predecir si Julia se convertirá en un lenguaje de programación tan común como R, por ejemplo, pero este año ya se ha convertido en el lenguaje de programación de más rápido crecimiento. Si solo unos pocos lo sabían el año pasado, este año, después del lanzamiento de la versión 1.0 y la estabilización de las funciones de la biblioteca, comenzaron a escribir sobre eso, casi con seguridad el próximo año se convertirá en un lenguaje que sería indecente no saber en el campo de la ciencia de datos. Y las compañías que no comenzaron a usar a Julia para analizar datos serían dinosaurios que serían reemplazados por descendientes más ágiles.
Julia es un lenguaje de programación joven. En realidad, después de la aparición de proyectos piloto, quedará claro cuánta infraestructura de Julia está lista para un uso industrial real. Los desarrolladores de Julia son muy ambiciosos y están listos ahora. En cualquier caso, la sintaxis simple pero estricta de Julia lo convierte en un lenguaje de programación muy atractivo para aprender en este momento. El alto rendimiento le permite implementar algoritmos que son adecuados no solo para fines educativos, sino también para un uso real en el análisis de datos. Comenzaremos a probar consistentemente a Julia en varios proyectos ahora.