
Julia é uma das mais novas linguagens de programação matemática, alegando ser a principal linguagem de programação nessa área. Infelizmente, no momento não há literatura suficiente em russo, e os materiais disponíveis em inglês contêm informações que, devido ao desenvolvimento dinâmico de Julia, nem sempre correspondem à versão atual, mas isso não é óbvio para os programadores iniciantes de Julia. Tentaremos preencher as lacunas e transmitir as idéias de Julia aos leitores na forma de exemplos simples.
O objetivo deste artigo é fornecer aos leitores uma idéia das maneiras básicas de trabalhar com tabelas na linguagem de programação Julia, a fim de incentivá-los a começar a usar essa linguagem de programação para processar dados reais. Assumimos que o leitor já esteja familiarizado com outras linguagens de programação; portanto, forneceremos apenas informações mínimas sobre como isso é feito, mas não entraremos em detalhes dos métodos de processamento de dados.
Obviamente, uma das etapas mais importantes no trabalho de um programa que realiza análise de dados é a importação e exportação. Além disso, o formato de apresentação de dados mais comum é uma tabela. Existem bibliotecas para Julia que fornecem acesso ao DBMS relacional, usam formatos de troca como HDF5, MATLAB, JLD. Mas, neste caso, estaremos interessados apenas no formato de texto para representar tabelas, como CSV.
Antes de examinar as tabelas, é necessário fazer uma pequena introdução à apresentação dessa estrutura de dados. Para Julia, uma tabela pode ser representada como uma matriz bidimensional ou como um DataFrame.
Matrizes
Vamos começar com as matrizes em Julia. A numeração dos elementos começa com um. Isso é bastante natural para os matemáticos e, além disso, o mesmo esquema é usado em Fortran, Pascal, Matlab. Para programadores que nunca usaram essas linguagens, essa numeração pode parecer desconfortável e causar erros ao escrever condições de contorno, mas, na realidade, isso é apenas uma questão de hábito. Depois de algumas semanas de uso de Julia, a questão de alternar entre modelos de linguagem não surge mais.
O segundo ponto significativo dessa linguagem é a representação interna de matrizes. Para Julia, uma matriz linear é uma coluna. Ao mesmo tempo, para linguagens como C, Java, uma matriz unidimensional é uma sequência.
Ilustramos isso com uma matriz criada na linha de comando (REPL)
julia> a = [1, 2, 3] 3-element Array{Int64,1}: 1 2 3
Preste atenção ao tipo da matriz - Matriz {Int64,1}. A matriz é unidimensional, tipo Int64. Além disso, se queremos combinar essa matriz com outra matriz, como estamos lidando com uma coluna, devemos usar a função vcat (ou seja, concatenar vertical). O resultado é uma nova coluna.
julia> b = vcat(a, [5, 6, 7]) 7-element Array{Int64,1}: 1 2 3 5 6 7
Se criarmos uma matriz como uma string, ao escrever um literal, usaremos espaços em vez de vírgulas e obteremos uma matriz bidimensional do tipo Array {Int64,2}. O segundo argumento na declaração de tipo significa o número de coordenadas da matriz multidimensional.
julia> c = [1 2 3] 1×3 Array{Int64,2}: 1 2 3
Ou seja, temos uma matriz com uma linha e três colunas.
Essa apresentação de linhas e colunas também é característica do Fortran e do Matlab, mas deve-se lembrar que Julia é uma linguagem orientada especificamente para o seu campo de aplicação.
A matriz para Julia é uma matriz bidimensional, onde todas as células são do mesmo tipo. Vamos prestar atenção ao fato de que o tipo pode ser abstrato Qualquer ou bastante específico, como Int64, Float64 ou, mesmo, String.
Podemos criar uma matriz na forma de um literal:
julia> a = [1 2; 3 4] 2×2 Array{Int64,2}: 1 2 3 4
Crie usando o construtor e aloque memória sem inicialização (undef):
julia> a = Array{Int64,2}(undef, 2, 3) 2×3 Array{Int64,2}: 4783881648 4783881712 4782818640 4783881680 4783881744 4782818576
Ou com inicialização se algum valor específico for especificado em vez de undef.
Cola de colunas 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
Inicialize aleatoriamente:
julia> x = rand(1:10, 2, 3) 2×3 Array{Int64,2}: 1 10 2 9 7 7
Argumentos aleatórios - variam de 1 a 10 e dimensão 2 x 3.
Ou use a inclusão (compreensões)
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
Observe que o fato de que para Julia as colunas são um bloco linear de memória leva ao fato de que a iteração sobre os elementos por coluna será significativamente mais rápida do que a classificação nas linhas. Em particular, o exemplo a seguir usa uma matriz de 1_000_000 linhas e 100 colunas.
#!/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 no exemplo é uma execução múltipla de uma função para calcular o tempo médio necessário para executar. Essa macro é fornecida pela biblioteca BenchmarkTools.jl. O kit base Julia possui uma macro de tempo , mas mede um intervalo único, que, nesse caso, será impreciso. A macro show simplesmente exibe a expressão e seu valor calculado no console.
A otimização do armazenamento em colunas é conveniente para executar operações estatísticas com uma tabela. Como tradicionalmente, a tabela é limitada pelo número de colunas e o número de linhas pode ser qualquer um, a maioria das operações, como o cálculo de valores médios, mínimos e máximos, são executadas especificamente para as colunas das matrizes e não para suas linhas.
Um sinônimo para uma matriz bidimensional é o tipo Matrix. No entanto, isso é mais uma conveniência de estilo do que uma necessidade.
O acesso aos elementos da matriz é realizado por índice. Por exemplo, para uma matriz criada anteriormente
julia> x = rand(1:10, 2, 3) 2×3 Array{Int64,2}: 1 10 2 9 7 7
Podemos obter um elemento específico como x [1, 2] => 10. Portanto, obtenha a coluna inteira, por exemplo, a segunda coluna:
julia> x[:, 2] 2-element Array{Int64,1}: 10 7
Ou a segunda linha:
julia> x[2, :] 3-element Array{Int64,1}: 9 7 7
Há também uma função selectdim útil, na qual você pode especificar o número ordinal da dimensão para a qual deseja fazer uma seleção, bem como os índices dos elementos dessa dimensão. Por exemplo, faça uma amostragem na 2ª dimensão (colunas) selecionando o 1º e o 3º índices. Essa abordagem é conveniente quando, dependendo das condições, você precisa alternar entre linhas e colunas. No entanto, isso é verdade para o caso multidimensional, quando o número de dimensões é maior que 2.
julia> selectdim(x, 2, [1, 3]) 2×2 view(::Array{Int64,2}, :, [1, 3]) with eltype Int64: 1 2 9 7
Funções para processamento estatístico de matrizes
Mais sobre matrizes unidimensionais
Matrizes multidimensionais
Funções da álgebra linear e matrizes de uma forma especial
A leitura de uma tabela de um arquivo pode ser feita usando a função readdlm implementada na biblioteca DelimitedFiles. Gravação - usando writedlm. Essas funções fornecem trabalho com arquivos com delimitadores, um caso especial do qual é o formato CSV.
Ilustramos com um exemplo da documentação:
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"
Nesse caso, você deve prestar atenção ao fato de que a tabela contém dados de tipos diferentes. Portanto, ao ler um arquivo, uma matriz do tipo Matriz {Qualquer, 2} é criada.
Outro exemplo é a leitura de tabelas contendo dados 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
Do ponto de vista da eficiência do processamento, essa opção é preferível, pois os dados serão apresentados de forma compacta. Ao mesmo tempo, uma restrição explícita nas tabelas representadas pela matriz é um requisito para uniformidade dos dados.
Recomendamos examinar os recursos completos do readdlm na documentação. Entre as opções adicionais, há a capacidade de especificar o modo de processamento dos cabeçalhos, pulando linhas, a função das células de processamento, etc.
Uma maneira alternativa de ler tabelas é a biblioteca CSV.jl. Comparada com readdlm e writedlm, essa biblioteca fornece significativamente mais controle sobre as opções de gravação e leitura, além de verificar dados em arquivos delimitados. No entanto, a diferença fundamental é que o resultado da função CSV.File pode ser materializado no tipo DataFrame.
Dataframes
A biblioteca DataFrames fornece suporte para a estrutura de dados do DataFrame, focada na apresentação de tabelas. A diferença fundamental da matriz aqui é que cada coluna é armazenada individualmente e cada coluna tem seu próprio nome. Lembramos que, para Julia, o modo de armazenamento em colunas, em geral, é natural. E, embora aqui tenhamos um caso especial de matrizes unidimensionais, é obtida uma solução ótima tanto em termos de velocidade quanto de flexibilidade na representação de dados, pois o tipo de cada coluna pode ser individual.
Vamos ver como criar um DataFrame.
Qualquer matriz pode ser convertida em um 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 │
A função converter converte dados para o tipo especificado. Assim, para o tipo DataFrame, os métodos da função convert são definidos na biblioteca DataFrames (de acordo com a terminologia Julia, existem funções, e a variedade de suas implementações com argumentos diferentes é chamada de métodos). Note-se que as colunas da matriz recebem automaticamente os nomes x1, x2. Ou seja, se agora solicitarmos nomes de colunas, os obteremos na forma de uma matriz:
julia> names(b) 2-element Array{Symbol,1}: :x1 :x2
E os nomes são apresentados em um formato como Symbol (conhecido no mundo Ruby).
Um DataFrame pode ser criado diretamente - vazio ou contendo alguns dados no momento da construção. Por exemplo:
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 │
Aqui, indicamos uma matriz com valores de coluna e uma matriz com os nomes dessas colunas. Construções da forma coletar (1: 3) são a conversão de um intervalo do iterador de 1 para 3 em uma matriz de valores.
O acesso às colunas é possível pelo nome e pelo índice.
É muito fácil adicionar uma nova coluna, escrevendo algum valor em todas as linhas existentes. Por exemplo, df acima, queremos adicionar a coluna Pontuação. Para fazer isso, precisamos escrever:
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 │
Assim como no caso de matrizes simples, podemos colar instâncias do DataFrame usando as funções vcat, hcat. No entanto, o vcat pode ser usado apenas com as mesmas colunas nas duas tabelas. Você pode alinhar um DataFrame, por exemplo, usando a seguinte função:
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
A função de nomes aqui obtém uma matriz de nomes de colunas. A função setdiff (s1, s2) no exemplo detecta todos os elementos de s1 que não estão em s2. Em seguida, expanda o DataFrame para esses elementos. vcat cola dois DataFrames e retorna o resultado. Usar retorno neste caso não é necessário, pois o resultado da última operação é óbvio.
Podemos verificar o 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 │
Observe que, em termos de convenções de nomenclatura em Julia, não é habitual usar sublinhados, mas a legibilidade é prejudicada. Também não é muito bom nessa implementação é que o DataFrame original é modificado. Porém, este exemplo é bom para ilustrar o processo de alinhamento de várias colunas.
É possível unir vários DataFrames por valores comuns em colunas usando a função de junção (por exemplo, colando duas tabelas com colunas diferentes por identificadores de usuários comuns).
O DataFrame é conveniente para visualização no console. Qualquer forma de saída: o uso da macro show , a função println etc. resultará na impressão de uma tabela no console em um formato fácil de ler. Se o DataFrame for muito grande, as linhas inicial e final serão exibidas. No entanto, você pode solicitar explicitamente a cabeça e cauda com as funções de cabeça e cauda, respectivamente.
Para o DataFrame, estão disponíveis funções de agrupamento e agregação de dados para a função especificada. Existem diferenças no que eles retornam. Pode ser uma coleção com um DataFrame que atenda aos critérios de agrupamento ou um único DataFrame em que os nomes das colunas serão formados a partir do nome original e do nome da função de agregação. Em essência, um esquema de divisão de aplicar e combinar é implementado. Ver Detalhes
Usaremos um exemplo da documentação com uma tabela de exemplo disponível como parte do pacote DataFrames.
julia> using DataFrames, CSV, Statistics julia> iris = CSV.read(joinpath(dirname(pathof(DataFrames)), "../test/data/iris.csv"));
Execute o agrupamento usando a função groupby. Especifique o nome da coluna de agrupamento e obtenha um resultado do tipo GroupedDataFrame, que contém uma coleção de DataFrames individuais coletados pelos valores da coluna de agrupamento.
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 │
O resultado pode ser convertido em uma matriz usando a função de coleta 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 usando a função por. Especifique o nome da coluna e a função de processamento do DataFrame recebido. A primeira etapa do trabalho é semelhante à função groupby - obtemos a coleção DataFrame. Para cada DataFrame, conte o número de linhas e coloque-as na coluna N. O resultado será colado em um único DataFrame e retornado como resultado da função 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 │
Bem, a última opção é a função agregada. Especificamos uma coluna para agrupar e uma função de agregação para as colunas restantes. O resultado é um DataFrame em que os nomes das colunas serão formados em nome das colunas de origem e o nome da função de agregação.
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 │
A função colwise aplica a função especificada a todas ou apenas as colunas DataFrame especificadas.
julia> colwise(mean, iris[1:4]) 4-element Array{Float64,1}: 5.843333333333335 3.057333333333334 3.7580000000000027 1.199333333333334
Uma função muito conveniente para obter um resumo da tabela é descrever. Exemplo 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 recursos de DataFrames .
Como no caso Matrix, você pode usar todas as funções estatísticas disponíveis no módulo Statistics no DataFrame. Consulte https://docs.julialang.org/en/v1/stdlib/Statistics/index.html
A biblioteca StatPlots.jl é usada para exibir graficamente o DataFrame. Veja Mais https://github.com/JuliaPlots/StatPlots.jl
Esta biblioteca implementa um conjunto de macros para simplificar a visualização.
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])

Na última linha, @df é a macro, df é o nome da variável com o DataFrame.
Query.jl pode ser uma biblioteca muito útil. Usando os mecanismos das macros e o canal de processamento, o Query.jl fornece uma linguagem de consulta especializada. Um exemplo é obter uma lista de pessoas com mais de 50 anos e o número de filhos que eles têm:
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 │
Ou um formulário com um 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 │
Veja mais detalhes
Os dois exemplos acima demonstram o uso de linguagens de consulta funcionalmente semelhantes ao dplyr ou LINQ. Além disso, esses idiomas não estão limitados ao Query.jl. Saiba mais sobre o uso desses idiomas com os DataFrames aqui .
O último exemplo usa o operador | |. Veja mais .
Este operador substitui o argumento na função que é indicada à direita dele. Em outras palavras:
julia> [1:5;] |> x->x.^2 |> sum |> inv 0.01818181818181818
Equivalente a:
julia> inv(sum( [1:5;] .^ 2 )) 0.01818181818181818
E a última coisa que gostaria de observar é a capacidade de gravar um DataFrame no formato de saída com um separador usando a 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 o resultado gravado:
> cat out.csv name,age,children John,23.0,3 Sally,42.0,5 Kirk,59.0,2
Conclusão
É difícil prever se Julia se tornará uma linguagem de programação tão comum quanto R, por exemplo, mas este ano já se tornou a linguagem de programação que mais cresce. Se apenas alguns soubessem disso no ano passado, este ano, após o lançamento da versão 1.0 e a estabilização das funções da biblioteca, eles começaram a escrever sobre ele, quase certamente, no próximo ano se tornará uma linguagem, seria indecente não saber no campo da ciência de dados. E as empresas que não começassem a usar Julia para analisar dados seriam dinossauros diretos a serem substituídos por descendentes mais ágeis.
Julia é uma jovem linguagem de programação. Na verdade, após o surgimento de projetos-piloto, ficará claro o quanto a infraestrutura de Julia está pronta para uso industrial real. Os desenvolvedores Julia são muito ambiciosos e estão prontos agora. De qualquer forma, a sintaxe simples mas estrita de Julia a torna uma linguagem de programação muito atraente para aprender no momento. O alto desempenho permite implementar algoritmos adequados não apenas para fins educacionais, mas também para uso real na análise de dados. Vamos começar a tentar consistentemente Julia em vários projetos agora.