Julia est un langage de programmation open-source, multi-plateformes, performant et de haut niveau, dédié au calcul technique.
Julia est propulsé par un compilateur JIT La compilation “Just-In-Time” (au dernier moment) se produit à l’exécution du programme, plutôt que d’être réalisée au préalable. Ceci permet d’offrir la performance d’un code compilé sans sacrifier la flexibilité des langages interprétés. Après une phase d’inférence de types, le compilateur génère une représentation intermédiaire LLVM qui est à son tour compilée sous forme de code natif. basé sur LLVM Low-Level Virtual Machine (LLVM) est une infrastructure de compilation permettant de produire, optimiser et compiler du code sous forme de représentation intermédiaire ou de code binaire natif., ce qui lui permet d’atteindre les mêmes performances que des langages comme C et FORTRAN tout en évitant d’avoir à écrire du code bas-niveau. Comme le code est compilé à la volée, il est possible de l’évaluer dans une console ou REPL Read-Eval-Print-Loop : Boucle de Lecture-Évaluation-Affichage, ce qui fait d’ailleurs partie des modes de développement recommandés.
Julia est un langage à typage dynamique, propose des fonctionnalités de multiple dispatchÉtant donné que le type des arguments passés aux fonctions est déterminé lors de l’exécution, le compilateur peut choisir une implémentation optimale adaptée aux arguments fournis ainsi qu’à l’architecture matérielle ciblée., et a été conçu pour le parallélisme et le calcul distribué.
Julia intègre un gestionnaire de paquets.
Julia intègre aussi une bibliothèque mathématique fournie, comprenant des fonctions spéciales (p.ex. Gamma). Le langage supporte aussi les nombres complexes par défaut.
Julia permet de faire de la méta-programmation et de la génération de code grâce à des macros inspirées des langages LISP.
Julia est né en 2012.
Affectation | answer = 42 x, y, z = 1, [1:10; ], "A string" x, y = y, x # échanger x et y |
Déclaration constante | const DATE_OF_BIRTH = 2012 |
Commentaire en fin de ligne | i = 1 # Ceci est un commentaire |
Commentaire délimité | #= Ceci est un autre commentaire =# |
Chainage | x = y = z = 1 # de droite à gauche 0 < x < 3 # true 5 < x != y < 5 # false |
Définition de fonction | function add_one(i) return i + 1 end |
Insertion de symboles LaTeX | \delta + [Tab] |
Opérations fondamentales | + , - ,* ,/ |
Exponentiation | 2^3 == 8 |
Division | 3/12 == 0.25 |
Division inverse | 7\3 == 3/7 |
Reste (modulo) | x % y ou rem(x,y) |
Négation | !true == false |
Égalité | a == b |
Non-égalité | a != b ou a ≠ b |
Inégalités strictes | < et > |
Infériorité large | <= ou ≤ |
Supériorité large | >= ou ≥ |
Opérations élément-par-élément | [1, 2, 3] .+ [1, 2, 3] == [2, 4, 6] [1, 2, 3] .* [1, 2, 3] == [1, 4, 9] |
Not a Number | isnan(NaN) plutôt que NaN == NaN |
Opérateur ternaire | a == b ? "Equal" : "Not equal" |
ET et OU logiques (court-circuités) | a && b et a || b |
Équivalence d’objets | a === b |
Rappeler le dernier résultat | ans |
Interrompre l’exécution | [Ctrl] + [C] |
Effacer l’écran | [Ctrl] + [L] |
Lancer un programme Julia (script) | include("filename.jl") |
Aide sur la fonction func |
?func |
Toutes les pages d’aide où func est mentionnée |
apropos("func") |
Mode de commandes shell | ; (en début de ligne) |
Mode du gestionnaire de paquets | ] (en début de ligne) |
Mode d’aide | ? (en début de ligne) |
Sortir d’un mode spécifique / Revenir au REPL | [Backspace] (en début de ligne) |
Sortir du REPL | exit() ou [Ctrl] + [D] |
Pour que Julia démarre plus rapidement, de nombreuses fonctionnalités
essentielles sont disponibles dans les bibliothèques standard, distribuées et
installées avec Julia. Pour appeler les fonctions de ces bibliothèques, utilisez
la commande : using PackageName
. Nous listons ici quelques bibliothèques
standard et fonctions fréquemment utilisées.
Random |
rand , randn , randsubseq |
Statistics |
mean , std , cor , median , quantile |
LinearAlgebra |
I , eigvals , eigvecs , det , cholesky |
SparseArrays |
sparse , SparseVector , SparseMatrixCSC |
Distributed |
@distributed , pmap , addprocs |
Dates |
DateTime , Date |
Les paquets doivent être enregistrés avant de
pouvoir être désignés par leur nom en utilisant le gestionnaire de paquets. La
plupart des commandes ci-dessous acceptent aussi une URL de dépôt git pour
identifier un paquet non-enregistré. Le gestionnaire de paquets de Julia 1.0
peut être utilisé de deux manières : en tapant using Pkg
puis en utilisant les
fonctions du module Pkg
, ou bien en entrant dans le mode REPL dédié à la
gestion des paquets à l’aide de la touche ]
(Pour revenir au REPL Julia
standard, tapez [BackSpace]
dans une ligne vide). NB: les nouvelles
fonctionnalités de Pkg
arrivent souvent dans le mode REPL interactif, avant
d’intégrer l’API du module Pkg
.
Pkg
dans un code JuliaLister les paquets installés (format pour humains) | Pkg.status() |
Lister les paquets installés (format pour traitement automatique) | Pkg.installed() |
Mettre à jour les paquets | Pkg.update() |
Installer PackageName |
Pkg.add("PackageName") |
Reconstruire PackageName |
Pkg.build("PackageName") |
Utiliser PackageName (après installation) |
using PackageName |
Supprimer PackageName |
Pkg.rm("PackageName") |
pkg
Installer PackageName |
add PackageName |
Supprimer PackageName |
rm PackageName |
Mettre à jour PackageName |
update PackageName |
Utiliser une version de développement | dev PackageName ou dev GitRepoUrl |
Après dev , revenir à une version publiée |
free PackageName |
Character | chr = 'C' |
String | str = "A string" |
Character code | Int('J') == 74 |
Character from code | Char(74) == 'J' |
Any UTF character | chr = '\uXXXX' # 4-digit HEX chr = '\UXXXXXXXX' # 8-digit HEX |
Loop through characters | for c in str println(c) end |
Concatenation | str = "Learn" * " " * "Julia" |
String interpolation | a = b = 2 println("a * b = $(a*b)") |
First matching character or regular expression | findfirst(isequal('i'), "Julia") == 4 |
Replace substring or regular expression | replace("Julia", "a" => "us") == "Julius" |
Last index (of collection) | lastindex("Hello") == 5 |
Number of characters | length("Hello") == 5 |
Regular expression | pattern = r"l[aeiou]" |
Subexpressions | str = "+1 234 567 890" pat = r"\+([0-9]) ([0-9]+)" m = match(pat, str) m.captures == ["1", "234"] |
All occurrences | [m.match for m = eachmatch(pat, str)] |
All occurrences (as iterator) | eachmatch(pat, str) |
Beware of multi-byte Unicode encodings in UTF-8:
10 == lastindex("Ångström") != length("Ångström") == 8
Strings are immutable.
Integer types | IntN and UIntN , with N ∈ {8, 16, 32, 64, 128} , BigInt |
Floating-point types | FloatN with N ∈ {16, 32, 64} BigFloat |
Minimum and maximum values by type | typemin(Int8) typemax(Int64) |
Complex types | Complex{T} |
Imaginary unit | im |
Machine precision | eps() # same as eps(Float64) |
Rounding | round() # floating-point round(Int, x) # integer |
Type conversions | convert(TypeName, val) # attempt/error typename(val) # calls convert |
Global constants | pi # 3.1415... π # 3.1415... im # real(im * im) == -1 |
More constants | using Base.MathConstants |
Julia does not automatically check for numerical overflow. Use package SaferIntegers for ints with overflow checking.
Many random number functions require using Random
.
Set seed | seed!(seed) |
Random numbers | rand() # uniform [0,1) randn() # normal (-Inf, Inf) |
Random from Other Distribution | using Distributions my_dist = Bernoulli(0.2) # For example rand(my_dist) |
Random subsample elements from A with inclusion probability p | randsubseq(A, p) |
Random permutation elements of A | shuffle(A) |
Déclaration | arr = Float64[] |
Pré-allocation | sizehint!(arr, 10^4) |
Accès et mutation | arr = Any[1,2] arr[1] = "Some text" |
Comparaison | a = [1:10;] b = a # b pointe vers a a[1] = -99 a == b # true |
Copie des éléments (distincte en mémoire) | b = copy(a) # un seul niveau b = deepcopy(a) # récursivement |
Sous-tableau de m à n |
arr[m:n] |
Tableau de n éléments, rempli de 0.0 |
zeros(n) |
Tableau de n éléments, rempli de 1.0 |
ones(n) |
Tableau de n éléments, non initialisé |
Vector{Type}(undef,n) |
n nombres équi-répartis entre start et stop |
range(start,stop=stop,length=n) |
n nombres (Int8 ) aléatoires |
rand(Int8, n) |
Remplir arr avec des val |
fill!(arr, val) |
Suppression d’un élément en fin de tableau | pop!(arr) |
Suppression d’un élément en début de tableau | popfirst!(a) |
Ajout d’un élément en fin de tableau | push!(arr, val) |
Ajout d’un élément en début de tableau | pushfirst!(arr, val) |
Suppression de l’élément d’indice idx |
deleteat!(arr, idx) |
Tri (en place) | sort!(arr) |
Concaténation de b à la suite de a (en place) |
append!(a,b) |
Test si val est un élément de arr |
in(val, arr) ou val in arr |
Produit scalaire | dot(a, b) == sum(a .* b) |
Changement de dimensions (si possible) | reshape(1:6, 3, 2)' == [1 2 3; 4 5 6] |
Conversion en chaîne de caractères (éléments séparés par delim ) |
join(arr, delim) |
For most linear algebra tools, use using LinearAlgebra
.
Identity matrix | I # just use variable I. Will automatically conform to dimensions required. |
Define matrix | M = [1 0; 0 1] |
Matrix dimensions | size(M) |
Select i th row |
M[i, :] |
Select i th column |
M[:, i] |
Concatenate horizontally | M = [a b] or M = hcat(a, b) |
Concatenate vertically | M = [a ; b] or M = vcat(a, b) |
Matrix transposition | transpose(M) |
Conjugate matrix transposition | M' or adjoint(M) |
Matrix trace | tr(M) |
Matrix determinant | det(M) |
Matrix rank | rank(M) |
Matrix eigenvalues | eigvals(M) |
Matrix eigenvectors | eigvecs(M) |
Matrix inverse | inv(M) |
Solve M*x == v |
M\v is better Numerically more stable and typically also faster. than inv(M)*v |
Moore-Penrose pseudo-inverse | pinv(M) |
Julia has built-in support for matrix decompositions.
Julia tries to infer whether matrices are of a special type (symmetric,
hermitian, etc.), but sometimes fails. To aid Julia in dispatching the
optimal algorithms, special matrices can be declared to have a structure
with functions like Symmetric
, Hermitian
, UpperTriangular
, LowerTriangular
,
Diagonal
, and more.
Tests conditionnels | if-elseif-else-end |
Boucle simple | for i in 1:10 println(i) end |
Boucle à indices multiples | for i in 1:10, j = 1:5 println(i*j) end |
Énumeration | for (idx, val) in enumerate(arr) println("the $idx-th element is $val") end |
Boucle “tant que” | while bool_expr # do stuff end |
Sortie de boucle prématurée | break |
Saut à l’itération suivante | continue |
Tous les arguments de fonctions sont passés par référence.
Par convention, les fonctions dont le nom se termine par !
changent (mutent)
au moins l’un de leurs arguments (en général le premier). Par exemple :
sort!(arr)
.
Les arguments positionnels sont séparés par une virgule. Ils sont obligatoires,
sauf si une valeur par défaut est fournie dans la signature de la fonction, au
moyen du signe =
. A partir du premier argument optionnel, tous les arguments
positionnels suivants doivent aussi être optionnels.
Les arguments par mot-clé sont identifiés par leur nom, et listés dans la signature de fonction après un point-virgule :
function func(req1, req2, opt1=dflt1; key1=dflt1, key2=dflt2)
# do stuff
end
Le point-virgule n’est pas nécessaire pour identifier les arguments par mot-clé lors de l’appel à la fonction :
func(val_req1, val_req2, key1=val_key1)
# opt1 et key2: valeur par défaut
Le mot-clé return
est optionnel. S’il n’est pas présent, la valeur de la
dernière expression évaluée est renvoyée.
On peut renvoyer plusieurs valeurs en utilisant un Tuple
: return (val1, val2)
Les arguments passés à Julia en ligne de commande (julia script.jl arg1
arg2...
) peuvent être récupérés dans la constante globale ARGS
:
for arg in ARGS
println(arg)
end
Les fonctions anonymes sont souvent utiles en conjonction avec des fonctions
d’ordre supérieur ou des listes en compréhension:
x -> x^2
.
Les fonctions peuvent accepter un nombre variable d’arguments:
function func(a...)
println(a)
end
func(1, 2, [3:5]) # tuple: (1, 2, UnitRange{Int64}[3:5])
Les déclarations de fonctions peuvent être imbriquées:
function outerfunction()
# do some outer stuff
function innerfunction()
# do inner stuff
# can access prior outer definitions
end
# do more outer stuff
end
Les fonctions peuvent spécifier un type pour leur arguments ainsi que leur résultat :
# accepte n'importe quel argument sous-typant un nombre,
# et le renvoie sous forme de chaîne de caractères
function stringifynumber(num::T)::String where T <: Number
return "$num"
end
Les fonctions peuvent être
“vectorisées”,
(appliquées élément-par-élément) en utilisant la syntaxe “.
” :
julia> using Statistics
julia> A = rand(3, 4);
# La soustraction est "broadcastée" ici
julia> B = A .- mean(A, dims=1)
3×4 Array{Float64,2}:
0.0387438 0.112224 -0.0541478 0.455245
0.000773337 0.250006 0.0140011 -0.289532
-0.0395171 -0.36223 0.0401467 -0.165713
julia> mean(B, dims=1)
1×4 Array{Float64,2}:
-7.40149e-17 7.40149e-17 1.85037e-17 3.70074e-17
Julia génère des versions spécialisées Le dispatch multiple choisit la méthode la plus adaptée aux types d’arguments fournis (dynamiquement, i.e sur la base des types de valeurs constatés lors de l’exécution). A partir du code de la méthode choisie, la spécialisation permet ensuite de générer un code binaire natif optimal pour les types d’arguments fournis. Tout ceci est différent de la surcharge de fonctions, qui s’appuie exclusivement sur les types connus à la compilation. de chaque fonction, pour chaque type de données passées en argument. Quand une fonction est appelée à nouveau pour les mêmes types d’arguments, une version précédemment spécialisée peut être ré-utilisées ce qui évite d’avoir à repasser par une phase de compilation.
Il est possible que l’ensemble des méthodes définies conduisent à des ambiguïtés potentielles, mais réaliser effectivement un appel à une méthode ambiguë provoque une erreur à l’exécution.
Des dépassements de pile (Stack Overflows) peuvent arriver lorsque des appels de fonctions récursives s’imbriquent sur trop de niveaux. Des techniques de trampoline peuvent être mises en place pour émuler l’optimisation de la récursivité terminale (Tail Call Optimization), que Julia ne réalise pas (encore ?) par défaut. Les situations de récursivité terminale peuvent aussi être récrites sous forme de boucle.
Dictionary | d = Dict(key1 => val1, key2 => val2, ...) d = Dict(:key1 => val1, :key2 => val2, ...) |
All keys (iterator) | keys(d) |
All values (iterator) | values(d) |
Loop through key-value pairs | for (k,v) in d println("key: $k, value: $v") end |
Check for key :k |
haskey(d, :k) |
Copy keys (or values) to array | arr = collect(keys(d)) arr = [k for (k,v) in d] |
Dictionaries are mutable; when symbols are used as keys, the keys are immutable.
Declaration | s = Set([1, 2, 3, "Some text"]) |
Union s1 ∪ s2 |
union(s1, s2) |
Intersection s1 ∩ s2 |
intersect(s1, s2) |
Difference s1 \\ s2 |
setdiff(s1, s2) |
Difference s1 △ s2 |
symdiff(s1, s2) |
Subset s1 ⊆ s2 |
issubset(s1, s2) |
Checking whether an element is contained in a set is done in O(1).
Appeler une fonction pour chaque élément de coll |
map(fun, coll) oumap(coll) do elem # faire qqch avec elem end |
Garder les valeurs satisfaisant un prédicat | filter(pred, coll) |
Liste en compréhension | arr = [f(elem) for elem in coll] |
Julia n’a pas de classes, et par conséquent pas de méthodes de classe. Les types Julia sont similaires à des classes sans méthode.
Les types abstraits peuvent être sous-typés, mais pas instanciés. Les types concrets ne peuvent être sous-typés.
Par défaut, les struct
s sont immutables. Les types immutables améliorent la
performance et sont thread-safe puisqu’on ne peut accéder à leurs instances
qu’en lecture.
Les types Union
permettent de représenter un ensemble de types.
Assertion de type, annotation | var::TypeName |
Déclaration de type | struct Programmer name::String birth_year::UInt16 fave_language::AbstractString end |
Déclaration de type mutable | remplacer struct par mutable struct |
Alias de type | const Nerd = Programmer |
Liste des constructeurs d’un type | methods(TypeName) |
Instanciation d’un type (construction d’une instance) | me = Programmer("Ian", 1984, "Julia") me = Nerd("Ian", 1984, "Julia") |
Déclaration d’un sous-type | abstract type Bird end struct Duck <: Bird pond::String end |
Type paramétrique | struct Point{T <: Real} x::T y::T end p =Point{Float64}(1,2) |
Type union | Union{Int, String} |
Parcours de la hiérarchie de types | supertype(TypeName) and subtypes(TypeName) |
Supertype universel | Any |
Liste des champs | fieldnames(TypeName) |
Liste des types des champs | TypeName.types |
Lorsqu’une définition de type inclut un constructeur interne, les
constructeurs externes par défaut ne sont plus disponibles. Ils doivent être
définis manuellement si nécessaire. Un constructeur interne est utile pour
garantir des invariants sur les champs d’un type. (Ces invariants pourront quand
même être enfreints par une modification directe des champs, à moins que le type
soit immutable). Le mot-clé new
utilisé dans un constructeur interne permet de
créer un objet du type adéquat.
Les paramètres de type sont invariants, c’est à dire que Point{Float64} <:
Point{Real}
est faux, alors même que Float64 <: Real
.
En revanche, les Tuple
sont covariants : Tuple{Float64} <: Tuple{Real}
.
La représentation interne d’un morceau de code après inférence de types peut
être consultée grâce à code_typed()
. Ceci est en particulier utile pour
identifier les endroits où des expressions de type Any
sont manipulées plutôt
que du code natif de type spécifique.
Programmers Null | nothing |
Missing Data | missing |
Not a Number in Float | NaN |
Filter missings | collect(skipmissing([1, 2, missing])) == [1,2] |
Replace missings | collect((df[:col], 1)) |
Check if missing | ismissing(x) not x == missing |
Lancer SomeExcep |
throw(SomeExcep()) |
Relancer l’exception courante | rethrow() |
Définir NewExcep |
struct NewExcep <: Exception v::String end Base.showerror(io::IO, e::NewExcep) = print(io, "A problem with $(e.v)!") throw(NewExcep("x")) |
Lever une erreur avec un message | error(msg) |
Gérer les exceptions | try # quelque chose de dangereux catch ex if isa(ex, SomeExcep) # gérer SomeExcep elseif isa(ex, AnotherExcep) # gérer AnotherExcep else # gérer les autres exceptions end finally # fait dans tous les cas end |
Les modules sont des espaces de noms séparés qui groupent des fonctionnalités similaires.
Définition de module | module PackageName # déclarations de fonctions, types... # 'export' rend les définitions accessibles end |
Inclure un fichier source | include("filename.jl") |
Chargement | # tous les noms exportés using ModuleName # uniquement x, y using ModuleName: x, y # uniquement ModuleName import ModuleName # uniquement x, y # accessibles à l'extension de méthodes import ModuleName: x, y import ModuleName.x, ModuleName.y |
Liste des définitions | # Liste des noms exportés par ModuleName names(ModuleName) # y compris non-exportés, obsolètes # et noms générés par le compilateur names(ModuleName, all::Bool) # y compris noms importés d'un autre module names(ModuleName, all::Bool, imported::Bool) |
Une fonction foo
rendue visible par using Foo
ne peut être étendue par une
nouvelle méthode qu’explicitement : function Foo.bar(...)
.
Avec import Foo.bar
, l’ajout de méthode peut être non qualifié :
function bar(...)
suffit.
Julia is homoiconic: programs are represented as data structures of the
language itself. In fact, everything is an expression Expr
.
Symbols are interned strings Only one copy of each distinct (immutable) string value is stored. prefixed with a colon. Symbols are more efficient and they are typically used as identifiers, keys (in dictionaries), or columns in data frames. Symbols cannot be concatenated.
Quoting :( ... )
or quote ... end
creates an expression, just
like Meta.parse(str)
This form is probably most familiar to
people with knowledge of dynamic SQL. The Meta.parse
function is similar
to Oracle”s and PostgreSQL”s EXECUTE IMMEDIATE
statement or SQL
Server’s sp_executesql()
procedure. , and Expr(:call, ...)
.
x = 1
line = "1 + $x" # some code
expr = Meta.parse(line) # make an Expr object
typeof(expr) == Expr # true
dump(expr) # generate abstract syntax tree
eval(expr) == 2 # evaluate Expr object: true
Macros allow generated code (i.e. expressions) to be included in a program.
Definition | macro macroname(expr) # do stuff end |
Usage | macroname(ex1, ex2, ...) or @macroname ex1, ex2, ... |
Built-in macros | @test # equal (exact) @test x ≈ y # isapprox(x, y) @assert # assert (unit test) @which # types used @time # time and memory statistics @elapsed # time elapsed @allocated # memory allocated @profile # profile @spawn # run at some worker @spawnat # run at specified worker @async # asynchronous task @distributed # parallel for loop @everywhere # make available to workers |
Rules for creating hygienic macros:
local
.eval
inside macro.$(esc(expr))
Parallel computing tools are available in the Distributed
standard library.
Launch REPL with N workers | julia -p N |
Number of available workers | nprocs() |
Add N workers | addprocs(N) |
See all worker ids | for pid in workers() println(pid) end |
Get id of executing worker | myid() |
Remove worker | rmprocs(pid) |
Run f with arguments args on pid | r = remotecall(f, pid, args...) # or: r = @spawnat pid f(args) ... fetch(r) |
Run f with arguments args on pid (more efficient) | remotecall_fetch(f, pid, args...) |
Run f with arguments args on any worker | r = @spawn f(args) ... fetch(r) |
Run f with arguments args on all workers | r = [@spawnat w f(args) for w in workers()] ... fetch(r) |
Make expr available to all workers | @everywhere expr |
Parallel for loop with reducerA reducer combines the results from different (independent) workers. function red | sum = @distributed (red) for i in 1:10^6 # do parallelstuff end |
Apply f to all elements in collection coll | pmap(f, coll) |
Workers are also known as concurrent/parallel processes.
Modules with parallel processing capabilities are best split into a functions file that contains all the functions and variables needed by all workers, and a driver file that handles the processing of data. The driver file obviously has to import the functions file.
A non-trivial (word count) example of a reducer function is provided by Adam DeConinck.
Read stream | stream = stdin for line in eachline(stream) # do stuff end |
Read file | open(filename) do file for line in eachline(file) # do stuff end end |
Read CSV file | using CSV data = CSV.read(filename) |
Write CSV file | using CSV CSV.write(filename, data) |
Save Julia Object | using JLD save(filename, "object_key", object, ...) |
Load Julia Object | using JLD d = load(filename) # Returns a dict of objects |
Save HDF5 | using HDF5 h5write(filename, "key", object) |
Load HDF5 | using HDF5 h5read(filename, "key") |
For dplyr
-like tools, see
DataFramesMeta.jl.
Read Stata, SPSS, etc. | StatFiles Package |
DescribeSimilar to summary(df) in R. data frame |
describe(df) |
Make vector of column col |
v = df[:col] |
Sort by col |
sort!(df, [:col]) |
CategoricalSimilar to df$col = as.factor(df$col) in R. col |
categorical!(df, [:col]) |
List col levels |
levels(df[:col]) |
All observations with col==val |
df[df[:col] .== val, :] |
Reshape from wide to long format | stack(df, [1:n; ]) stack(df, [:col1, :col2, ...]) melt(df, [:col1, :col2]) |
Reshape from long to wide format | unstack(df, :id, :val) |
Make Nullable |
allowmissing!(df) or allowmissing!(df, :col) |
Loop over Rows | for r in eachrow(df) # do stuff. # r is Struct with fields of col names. end |
Loop over Columns | for c in eachcol(df) # do stuff. # c is tuple with name, then vector end |
Apply func to groups | by(df, :group_col, func) |
Query | using Query query = @from r in df begin @where r.col1 > 40 @select {new_name=r.col1, r.col2} @collect DataFrame # Default: iterator end |
Type | typeof(name) |
Type check | isa(name, TypeName) |
List subtypes | subtypes(TypeName) |
List supertype | supertype(TypeName) |
Function methods | methods(func) |
JIT bytecode | code_llvm(expr) |
Assembly code | code_native(expr) |
Many core packages are managed by communities with names of the form Julia[Topic].
Statistics | JuliaStats |
Differential Equations | JuliaDiffEq (DifferentialEquations.jl) |
Automatic differentiation | JuliaDiff |
Numerical optimization | JuliaOpt |
Plotting | JuliaPlots |
Network (Graph) Analysis | JuliaGraphs |
Web | JuliaWeb |
Geo-Spatial | JuliaGeo |
Machine Learning | JuliaML |
Super-used Packages | DataFrames # linear/logistic regression Distributions # Statistical distributions Flux # Machine learning Gadfly # ggplot2-likeplotting LightGraphs # Network analysis TextAnalysis # NLP |
The main convention in Julia is to avoid underscores unless they are required for legibility.
Variable names are in lower (or snake) case: somevariable
.
Constants are in upper case: SOMECONSTANT
.
Functions are in lower (or snake) case: somefunction
.
Macros are in lower (or snake) case: @somemacro
.
Type names are in initial-capital camel case: SomeType
.
Julia files have the jl
extension.
For more information on Julia code style visit the manual: style guide .
sizehint!
for large arrays.arr = nothing
.disable_gc()
....
) operator for keyword arguments.!
to avoid copying data structures.try
-catch
in (computation-intensive) loops.Any
in collections.eval
at run-time.