Julia. Travailler avec des tables


Julia est l'un des plus jeunes langages de programmation mathĂ©matique, prĂ©tendant ĂȘtre le principal langage de programmation dans ce domaine. Malheureusement, pour le moment, il n'y a pas assez de littĂ©rature en russe et les documents disponibles en anglais contiennent des informations qui, en raison du dĂ©veloppement dynamique de Julia, ne correspondent pas toujours Ă  la version actuelle, mais cela n'est pas Ă©vident pour les programmeurs dĂ©butants Julia. Nous essaierons de combler les lacunes et de transmettre les idĂ©es de Julia aux lecteurs sous forme d'exemples simples.


Le but de cet article est de donner aux lecteurs une idée des méthodes de base de travail avec les tables dans le langage de programmation Julia afin de les encourager à commencer à utiliser ce langage de programmation pour traiter des données réelles. Nous supposons que le lecteur connaßt déjà d'autres langages de programmation, nous ne donnerons donc que des informations minimales sur la façon dont cela est fait, mais nous n'entrerons pas dans les détails des méthodes de traitement des données.


Bien entendu, l'une des étapes les plus importantes du travail d'un programme qui effectue une analyse des données est leur importation et leur exportation. De plus, le format de présentation des données le plus courant est un tableau. Il existe des bibliothÚques pour Julia qui donnent accÚs aux SGBD relationnels, utilisent des formats d'échange tels que HDF5, MATLAB, JLD. Mais dans ce cas, nous ne nous intéresserons qu'au format texte pour représenter les tableaux, comme CSV.


Avant de regarder les tableaux, vous devez faire une petite introduction Ă  la prĂ©sentation de cette structure de donnĂ©es. Pour Julia, une table peut ĂȘtre reprĂ©sentĂ©e comme un tableau Ă  deux dimensions ou comme un DataFrame.


Tableaux


Commençons par les tableaux de Julia. La numĂ©rotation des Ă©lĂ©ments commence par un. C'est tout Ă  fait naturel pour les mathĂ©maticiens, et en plus, le mĂȘme schĂ©ma est utilisĂ© dans Fortran, Pascal, Matlab. Pour les programmeurs qui n'ont jamais utilisĂ© ces langages, cette numĂ©rotation peut sembler inconfortable et provoquer des erreurs lors de l'Ă©criture des conditions aux limites, mais en rĂ©alitĂ©, ce n'est qu'une question d'habitude. AprĂšs quelques semaines d'utilisation de Julia, la question de basculer entre les modĂšles linguistiques ne se pose plus.


Le deuxiĂšme point significatif de ce langage est la reprĂ©sentation interne des tableaux. Pour Julia, un tableau linĂ©aire est une colonne. Dans le mĂȘme temps, pour des langages comme C, Java, un tableau unidimensionnel est une chaĂźne.


Nous illustrons cela avec un tableau créé sur la ligne de commande (REPL)


julia> a = [1, 2, 3] 3-element Array{Int64,1}: 1 2 3 

Faites attention au type du tableau - Array {Int64,1}. Le tableau est unidimensionnel, tapez Int64. De plus, si nous voulons combiner ce tableau avec un autre tableau, alors, comme nous avons affaire à une colonne, nous devons utiliser la fonction vcat (c'est-à-dire concaténer vertical). Le résultat est une nouvelle colonne.


 julia> b = vcat(a, [5, 6, 7]) 7-element Array{Int64,1}: 1 2 3 5 6 7 

Si nous créons un tableau sous forme de chaßne, lors de l'écriture d'un littéral, nous utilisons des espaces au lieu de virgules et obtenons un tableau à deux dimensions de type Array {Int64,2}. Le deuxiÚme argument de la déclaration de type signifie le nombre de coordonnées du tableau multidimensionnel.


 julia> c = [1 2 3] 1×3 Array{Int64,2}: 1 2 3 

Autrement dit, nous avons obtenu une matrice avec une ligne et trois colonnes.


Cette présentation des lignes et des colonnes est également caractéristique de Fortran et Matlab, mais il ne faut que rappeler que Julia est une langue spécifiquement orientée vers leur domaine d'application.


La matrice de Julia est un tableau Ă  deux dimensions, oĂč toutes les cellules sont du mĂȘme type. Prenons attention au fait que le type peut ĂȘtre abstrait Any ou tout Ă  fait spĂ©cifique, comme Int64, Float64 ou mĂȘme String.


Nous pouvons créer une matrice sous la forme d'un littéral:


 julia> a = [1 2; 3 4] 2×2 Array{Int64,2}: 1 2 3 4 

Créez à l'aide du constructeur et allouez de la mémoire sans initialisation (undef):


 julia> a = Array{Int64,2}(undef, 2, 3) 2×3 Array{Int64,2}: 4783881648 4783881712 4782818640 4783881680 4783881744 4782818576 

Ou avec initialisation si une valeur spécifique est spécifiée au lieu de undef.


Colle de colonnes séparées:


 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 

Initialisez au hasard:


 julia> x = rand(1:10, 2, 3) 2×3 Array{Int64,2}: 1 10 2 9 7 7 

Arguments rand - va de 1 Ă  10 et dimension 2 x 3.


Ou utilisez l'inclusion (Compréhensions)


 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 

Notez que le fait que pour Julia les colonnes soient un bloc de mémoire linéaire conduit au fait que l'itération sur les éléments par colonne sera beaucoup plus rapide que le tri sur les lignes. En particulier, l'exemple suivant utilise une matrice de 1_000_000 lignes et 100 colonnes.


 #!/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) 

RĂ©sultats:


  74.378 ms (1 allocation: 16 bytes) =# @btime(sumbycolumns(x)) = 50053093495 206.346 ms (1 allocation: 16 bytes) =# @btime(sumbyrows(x)) = 50053093495 

@btime dans l'exemple est une exécution multiple d'une fonction pour calculer le temps moyen qu'il faut pour s'exécuter. Cette macro est fournie par la bibliothÚque BenchmarkTools.jl. Le kit de base Julia a une macro de temps , mais il mesure un seul intervalle, qui, dans ce cas, sera inexact. La macro show affiche simplement l'expression et sa valeur calculée dans la console.


L'optimisation du stockage sur colonne est pratique pour effectuer des opĂ©rations statistiques avec une table. Étant donnĂ© que traditionnellement, le tableau est limitĂ© par le nombre de colonnes et que le nombre de lignes peut ĂȘtre quelconque, la plupart des opĂ©rations, telles que le calcul des valeurs moyennes, minimales et maximales, sont effectuĂ©es spĂ©cifiquement pour les colonnes des matrices, et non pour leurs lignes.


Un synonyme d'un tableau à deux dimensions est le type Matrix. Cependant, c'est plutÎt une commodité de style plutÎt qu'une nécessité.


L'accÚs aux éléments de la matrice se fait par index. Par exemple, pour une matrice créée précédemment


 julia> x = rand(1:10, 2, 3) 2×3 Array{Int64,2}: 1 10 2 9 7 7 

Nous pouvons obtenir un élément spécifique comme x [1, 2] => 10. Donc, obtenez la colonne entiÚre, par exemple, la deuxiÚme colonne:


 julia> x[:, 2] 2-element Array{Int64,1}: 10 7 

Ou la deuxiĂšme ligne:


 julia> x[2, :] 3-element Array{Int64,1}: 9 7 7 

Il existe Ă©galement une fonction selectdim utile, oĂč vous pouvez spĂ©cifier le numĂ©ro ordinal de la dimension pour laquelle vous souhaitez effectuer une sĂ©lection, ainsi que les indices des Ă©lĂ©ments de cette dimension. Par exemple, faites un Ă©chantillonnage Ă  la 2e dimension (colonnes) en sĂ©lectionnant les 1er et 3e indices. Cette approche est pratique lorsque, selon les conditions, vous devez basculer entre les lignes et les colonnes. Cependant, cela est vrai pour le cas multidimensionnel, lorsque le nombre de dimensions est supĂ©rieur Ă  2.


 julia> selectdim(x, 2, [1, 3]) 2×2 view(::Array{Int64,2}, :, [1, 3]) with eltype Int64: 1 2 9 7 

Fonctions de traitement statistique des tableaux
En savoir plus sur les tableaux unidimensionnels
Tableaux multidimensionnels
Fonctions d'algÚbre linéaire et matrices d'une forme spéciale


La lecture d'une table Ă  partir d'un fichier peut ĂȘtre effectuĂ©e Ă  l'aide de la fonction readdlm implĂ©mentĂ©e dans la bibliothĂšque DelimitedFiles. Enregistrement - en utilisant writedlm. Ces fonctions permettent de travailler avec des fichiers avec dĂ©limiteurs, dont le cas particulier est le format CSV.


Nous illustrons avec un exemple de la documentation:


 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" 

Dans ce cas, vous devez faire attention au fait que la table contient des données de différents types. Par conséquent, lors de la lecture d'un fichier, une matrice de type Array {Any, 2} est créée.
Un autre exemple est la lecture de tableaux contenant des données homogÚnes.


 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 

Du point de vue de l'efficacitĂ© du traitement, cette option est prĂ©fĂ©rable, car les donnĂ©es seront prĂ©sentĂ©es de maniĂšre compacte. Dans le mĂȘme temps, une restriction explicite des tables reprĂ©sentĂ©es par la matrice est une exigence d'uniformitĂ© des donnĂ©es.


Nous vous recommandons de consulter les fonctionnalitĂ©s complĂštes de readdlm dans la documentation. Parmi les options supplĂ©mentaires, il y a la possibilitĂ© de spĂ©cifier le mode de traitement des en-tĂȘtes, les lignes Ă  sauter, la fonction de traitement des cellules, etc.


Une autre façon de lire les tableaux est la bibliothĂšque CSV.jl. ComparĂ©e Ă  readdlm et writedlm, cette bibliothĂšque offre un contrĂŽle beaucoup plus important sur les options d'Ă©criture et de lecture, ainsi que la vĂ©rification des donnĂ©es dans des fichiers dĂ©limitĂ©s. Cependant, la diffĂ©rence fondamentale est que le rĂ©sultat de la fonction CSV.File peut ĂȘtre matĂ©rialisĂ© dans le type DataFrame.


Cadres de données


La bibliothĂšque DataFrames prend en charge la structure de donnĂ©es DataFrame, qui se concentre sur la prĂ©sentation des tableaux. La diffĂ©rence fondamentale avec la matrice ici est que chaque colonne est stockĂ©e individuellement et chaque colonne a son propre nom. Nous rappelons que pour Julia, le mode de stockage par colonne, en gĂ©nĂ©ral, est naturel. Et, bien que nous ayons ici un cas particulier de tableaux unidimensionnels, une solution optimale est obtenue Ă  la fois en termes de vitesse et de flexibilitĂ© de reprĂ©sentation des donnĂ©es, car le type de chaque colonne peut ĂȘtre individuel.


Voyons comment créer un DataFrame.


Toute matrice peut ĂȘtre convertie en 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 fonction de conversion convertit les données dans le type spécifié. En conséquence, pour le type DataFrame, les méthodes de la fonction convert sont définies dans la bibliothÚque DataFrames (selon la terminologie Julia, il existe des fonctions et la variété de leurs implémentations avec différents arguments est appelée méthodes). Il est à noter que les colonnes de la matrice se voient automatiquement attribuer les noms x1, x2. Autrement dit, si nous demandons maintenant des noms de colonnes, nous les obtiendrons sous la forme d'un tableau:


 julia> names(b) 2-element Array{Symbol,1}: :x1 :x2 

Et les noms sont présentés dans un format comme Symbol (bien connu dans le monde Ruby).


Un DataFrame peut ĂȘtre crĂ©Ă© directement - vide ou contenant des donnĂ©es au moment de la construction. Par exemple:


 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 │ 

Ici, nous indiquons un tableau avec les valeurs des colonnes et un tableau avec les noms de ces colonnes. Les constructions du formulaire collect (1: 3) sont la conversion d'une plage d'itérateurs de 1 à 3 en un tableau de valeurs.


L'accĂšs aux colonnes est possible Ă  la fois par leur nom et par leur index.


Il est trĂšs facile d'ajouter une nouvelle colonne en Ă©crivant une valeur dans toutes les lignes existantes. Par exemple, df ci-dessus, nous voulons ajouter la colonne Score. Pour ce faire, nous devons Ă©crire:


 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 │ 

Comme pour les matrices simples, nous pouvons coller des instances DataFrame en utilisant les fonctions vcat, hcat. Cependant, vcat ne peut ĂȘtre utilisĂ© qu'avec les mĂȘmes colonnes dans les deux tables. Vous pouvez aligner un DataFrame, par exemple, en utilisant la fonction suivante:


 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 fonction names obtient ici un tableau de noms de colonnes. La fonction setdiff (s1, s2) dans l'exemple détecte tous les éléments de s1 qui ne sont pas dans s2. Ensuite, développez le DataFrame à ces éléments. vcat colle deux DataFrames et renvoie le résultat. Dans ce cas, l'utilisation de return n'est pas nécessaire, car le résultat de la derniÚre opération est évident.


Nous pouvons vérifier le résultat:


 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 │ 

Notez qu'en termes de conventions de dénomination dans Julia, il n'est pas habituel d'utiliser des traits de soulignement, mais la lisibilité en souffre. Ce qui n'est pas non plus trÚs bien dans cette implémentation, c'est que le DataFrame d'origine est modifié. Mais, néanmoins, cet exemple est bon pour illustrer le processus d'alignement de plusieurs colonnes.


La jointure de plusieurs DataFrames par des valeurs communes dans des colonnes est possible en utilisant la fonction de jointure (par exemple, en collant deux tables avec des colonnes différentes par des identifiants d'utilisateurs communs).


DataFrame est pratique pour la visualisation dans la console. N'importe quel moyen de sortie: en utilisant la macro show , en utilisant la fonction println, etc., un tableau sera imprimĂ© sur la console sous une forme facile Ă  lire. Si le DataFrame est trop volumineux, les lignes de dĂ©but et de fin seront affichĂ©es. Cependant, vous pouvez demander explicitement la tĂȘte et la queue avec les fonctions tĂȘte et queue, respectivement.


Pour DataFrame, des fonctions de regroupement et d'agrĂ©gation de donnĂ©es pour la fonction spĂ©cifiĂ©e sont disponibles. Il y a des diffĂ©rences dans ce qu'ils rendent. Cela peut ĂȘtre une collection avec un DataFrame qui rĂ©pond aux critĂšres de regroupement, ou un seul DataFrame oĂč les noms de colonne seront formĂ©s Ă  partir du nom d'origine et du nom de la fonction d'agrĂ©gation. Essentiellement, un schĂ©ma de rĂ©partition-application-combinaison est mis en Ɠuvre. Voir les dĂ©tails


Nous utiliserons un exemple de la documentation avec un exemple de table disponible dans le cadre du package DataFrames.


 julia> using DataFrames, CSV, Statistics julia> iris = CSV.read(joinpath(dirname(pathof(DataFrames)), "../test/data/iris.csv")); 

Effectuez le regroupement à l'aide de la fonction groupby. Spécifiez le nom de la colonne de regroupement et obtenez un résultat du type GroupedDataFrame, qui contient une collection de DataFrames individuels collectés par les valeurs de la colonne de regroupement.


 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 │ 

Le rĂ©sultat peut ĂȘtre converti en un tableau Ă  l'aide de la fonction de collecte mentionnĂ©e prĂ©cĂ©demment:


 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 │ 
 

Regroupez en utilisant la fonction by. Spécifiez le nom de la colonne et la fonction de traitement du DataFrame reçu. La premiÚre étape du travail par est similaire à la fonction groupby - nous obtenons la collection DataFrame. Pour chacun de ces DataFrame, comptez le nombre de lignes et placez-les dans la colonne N. Le résultat sera collé dans un seul DataFrame et renvoyé comme résultat de la fonction 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 │ 

Eh bien, la derniĂšre option est la fonction d'agrĂ©gation. Nous spĂ©cifions une colonne pour le regroupement et une fonction d'agrĂ©gation pour les colonnes restantes. Le rĂ©sultat est un DataFrame oĂč les noms de colonne seront formĂ©s au nom des colonnes source et le nom de la fonction d'agrĂ©gation.


 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 fonction colwise applique la fonction spécifiée à toutes ou uniquement aux colonnes DataFrame spécifiées.


 julia> colwise(mean, iris[1:4]) 4-element Array{Float64,1}: 5.843333333333335 3.057333333333334 3.7580000000000027 1.199333333333334 

Une fonction trÚs pratique pour obtenir un résumé du tableau est décrite. Exemple d'utilisation:


 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 │ 

Liste complÚte des fonctionnalités DataFrames .


Comme pour le cas Matrix, vous pouvez utiliser toutes les fonctions statistiques disponibles dans le module Statistics du DataFrame. Voir https://docs.julialang.org/en/v1/stdlib/Statistics/index.html


La bibliothÚque StatPlots.jl est utilisée pour afficher graphiquement le DataFrame. Voir plus https://github.com/JuliaPlots/StatPlots.jl
Cette bibliothÚque implémente un ensemble de macros pour simplifier la visualisation.


 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]) 


Dans la derniĂšre ligne, @df est la macro, df est le nom de la variable avec le DataFrame.


Query.jl peut ĂȘtre une bibliothĂšque trĂšs utile. En utilisant les mĂ©canismes des macros et le canal de traitement, Query.jl fournit un langage de requĂȘte spĂ©cialisĂ©. Un exemple est d'obtenir une liste des personnes de plus de 50 ans et le nombre d'enfants qu'elles ont:


 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 un formulaire avec 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 │ 

Voir plus de détails


Les deux exemples ci-dessus montrent l'utilisation de langages de requĂȘte fonctionnellement similaires Ă  dplyr ou LINQ. De plus, ces langues ne sont pas limitĂ©es Ă  Query.jl. En savoir plus sur l'utilisation de ces langages avec DataFrames ici .


Le dernier exemple utilise l'opérateur | |. Voir plus .


Cet opérateur substitue l'argument à la fonction indiquée à sa droite. En d'autres termes:


 julia> [1:5;] |> x->x.^2 |> sum |> inv 0.01818181818181818 

Équivalent à:


 julia> inv(sum( [1:5;] .^ 2 )) 0.01818181818181818 

Et la derniÚre chose que je voudrais noter est la possibilité d'écrire un DataFrame au format de sortie avec un séparateur en utilisant la bibliothÚque CSV.jl mentionnée précédemment


 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" 

Nous pouvons vérifier le résultat enregistré:


 > cat out.csv name,age,children John,23.0,3 Sally,42.0,5 Kirk,59.0,2 

Conclusion


Il est difficile de prédire si Julia deviendra un langage de programmation aussi commun que R, par exemple, mais cette année, il est déjà devenu le langage de programmation à la croissance la plus rapide. Si seulement quelques-uns le savaient l'année derniÚre, cette année, aprÚs la sortie de la version 1.0 et la stabilisation des fonctions de bibliothÚque, ils ont commencé à écrire à ce sujet, l'année prochaine, il deviendra certainement un langage qu'il serait indécent de ne pas connaßtre dans le domaine de la science des données. Et les entreprises qui n'ont pas commencé à utiliser Julia pour analyser les données seraient carrément des dinosaures à remplacer par des descendants plus agiles.


Julia est un jeune langage de programmation. En fait, aprĂšs l'apparition de projets pilotes, il sera clair combien l'infrastructure de Julia est prĂȘte pour une utilisation industrielle rĂ©elle. Les dĂ©veloppeurs de Julia sont trĂšs ambitieux et sont prĂȘts maintenant. Dans tous les cas, la syntaxe simple mais stricte de Julia en fait un langage de programmation trĂšs attractif pour l'apprentissage dĂšs maintenant. Les hautes performances vous permettent d'implĂ©menter des algorithmes qui conviennent non seulement Ă  des fins pĂ©dagogiques, mais Ă©galement Ă  une utilisation rĂ©elle dans l'analyse de donnĂ©es. Nous allons commencer Ă  essayer rĂ©guliĂšrement Julia dans divers projets maintenant.

Source: https://habr.com/ru/post/fr429994/


All Articles