Julia Data Science¶
Welcome - Julia Data Science (julialang.org)
第一章 前言¶
- 什么是数据科学?
- 数字素养
- 操作数据
- 可视化数据
- 软件工程
第二章 为什么选择 Julia¶
- 从未编过程
- 有编程经验
- 使用 Julia,Python 或 R 的分钟级运行时间可能会缩短为秒级
- 在 Julia 中,你可以自定义各种各样的代码
- 在 Julia 中,你仅需要阅读 Julia 代码,并且不需要学习其他语言来加速原来的代码
- Julia 用户能够轻松地共享和重用来自不同包的代码
- 而 Julia 有着令人惊叹的项目管理方案和绝佳的包管理器
- Julia 想实现什么?
- 简单且快速、大规模的数据与计算、容易地创建和操作原型代码
- Julia vs. 其他编程语言
- 两语言问题
- 发原型(易编程)和方案实现 (速度快)将采用相同的语言
- 代码和数学关系的一对一
- 多重派发
- Julia 应用案例
第三章 Julia 基础¶
- 开发环境
- 语法
- Julia 是一种即时编译的动态类型语言
- Julia 允许用户进行类型声明
- Julia 允许用户通过多重派发定义不同参数类型组合的函数行为
- 变量
- 整数和实数默认使用 64 位存储
- 使用 typeof() 函数可以查看变量的类型
- methodswith() 函数,它可以为输出所有可用于指定类型的函数
- 用户定义类型
- 使用 struct(也称为复合类型)来定义结构化数据
- 可以通过将 struct 作为参数传递给 fieldnames() 检查字段名称列表
- 要使用 struct,必须创建单个实例(或 “对象”)
- fieldnames() 函数可检查字段名称列表
- struct 实例的值在构造后无法修改。如果需要,可以创建 mutable struct
- 可变对象一般来说更慢且更容易出现错误。因此,尽可能确保所有类型都是不可变的
- 布尔运算和数值比较
- 函数
- 函数声明以关键字 function 开始,后接函数名称。然后在 "()" 里定义参数,这些参数由 "," 分隔。接着在函数体内部定义我们希望 Julia 对传入参数执行的操作。函数里定义的所有变量都会在函数返回后删除。
- 紧凑的赋值形式
- 如果想定义关于所有浮点数和整数类型的函数,那么需要使用 abstract type 作为函数签名,例如 AbstractFloat 或 Integer
- 可以使用 supertypes() 和 subtypes() 函数查看类型间的关系
- struct 有基本的输出样式,可以为自定义类型定义新的 Base.show() 方法
- 多返回值
- 与返回值的形式类似,依次为每个返回值定义一个变量
- 定义一个变量来接受所有的返回值,然后通过 first() 或 last() 访问每个返回值
- 关键字参数
- 某些函数可以接受关键字参数而不是位置参数。这些参数与常规参数类似,只是定义在常规函数参数之后且使用分号";" 分隔。
- 匿名函数
- 很多情况下,我们不关心函数名称,只想快速创建函数。因此我们需要匿名函数
- 使用 −>,−> 的左侧定义参数名称。−> 的右侧定义了想对左侧参数进行的操作。
- 条件表达式 If-Elseif-Else
- for 循环
- while 循环
- 在条件语句中,循环和函数内定义的变量仅存在于其内部。这就是变量的作用域。我们需要通过 global 关键字告诉 Julia while 循环中的 n 是全局作用域中的 n
- 原生数据结构
- 它们都能够保存同类型或异构的数据。因为它们都是集合, 所以都能通过 for 循环进行遍历。
- 对运算符和函数进行广播
- 可以使用点运算符广播像 ∗(乘)或 +(加)这样的数学运算
- 函数也能通过这种操作实现广播
- 带感叹号 ! 的函数
- 当函数改变了一个或多个它们的参数时,按照 Julia 惯例,应该在函数名后追加 !。这个惯例警告用户该函数并不单纯,它具有副作用。
- 字符串
- 使用双引号分隔符表示字符串
- 也可以定义一个多行字符串
- 使用三引号通常更清晰
- 当使用三引号时,Julia 会忽略开头的缩进和换行。
- 字符串连接
- ∗ 运算符或 join() 函数
- 字符串插值
- 使用美元符号 $ 在字符串中插入你想包含的内容
- 字符串处理
- contains(),startswith() 与 endswith()
- lowercase(),uppercase(),titlecase() 与 lowercasefirst()
- replace()
- split()
- 字符串转换
- 可以使用 string() 函数将数字转为字符串。
- 函数 parse() 将字符串转为数字。
- 希望能够安全地进行这些转换。此时就需要介绍 tryparse() 函数。
- 元组
- 元组是包含多种不同类型的固定长度容器。同时元组是不可变对象
- 命名元组
- 快捷语法。在命名元组的构造开始时,首先在值之前添加 ";"
- 当组成命名元组的值已经在变量中定义,或者你想避免过长的行时,这一语法非常有用
- Ranges
- start:stop
- start:step:stop
- 将 range“实例化” 到集合中,可以使用函数 collect()
- 数组
- 数组类型
- Vector{T}
- 一维数组。Array{T, 1} 的别名。
- Matrix{T}
- 二维数组。Array{T, 2} 的别名。
- Vector{T}
- 数组构造
- 用于 Julia 数组的低级构造器是默认构造器
- 它接手元素类型作为 "{}" 括号内的类型参数,并将元素类型传递到构造器里,构造器后跟需要的维度。
- 语法别名
- zeros(), ones()
- 使用 fill! 函数将想要的元素填充到数组的每一个元素上
- 可以使用数组字面量创建数组
- 数组字面量能在 "[]" 括号前接收指定的类型
- 数组推断
- 串联函数创建数组
- cat()
- 沿着指定的 dims 串联输入的数组
- vcat()
- 垂直串联,cat(...; dims=1) 的缩写
- cat()
- 数组检测
- eltype(): 数组中的元素类型
- length(): 元素的总数
- ndims(): 维度的个数
- size(): 默认情况下将返回包含所有数组维度的元组
- 数组索引和切片
- Julia 也为数组的第一个和最后一个元素定义了特殊的关键字:begin 和 end
- 类似 matlab
- 数组操作
- 数组的单个元素或数组的子集,索引或切片赋值
- 改变形状
- 第三种操作数组的方式是按元素应用函数。这会用到点运算符 ".",其也被称为广播
- 另一种在向量中广播函数的方法是使用 map()
- mapslices() 函数可以沿着特定的数组维度应用函数
- 数组迭代
- 常见的操作是使用 for 循环迭代数组。应用于数组的 for 循环会逐个返回元素
- 使用 eachindex() 函数结合 for 循环来迭代每个数组索引
- Julia 是 “列优先存储”
- 进行这些循环时使用特定的函数
- eachcol: 先沿着列方向迭代
- eachrow: 先沿着行方向迭代
- 进行这些循环时使用特定的函数
- 数组类型
- Pair
- Pair 是一种包含两个对象的数据结构
- 这两个元素分别存储在字段 first 和 second
- 在大多数情况下,使用 first() 和 last() 更简单
- 字典
- 构造
- 向 Dict 构造器传递由 (key, value) 元组构成的向量
- 向 Dict 构造器传递多组 key => value
- 使用 zip() 函数将两个对象 “粘合” 起来
- 使用相应的 key 作为索引即可检索到 Dict 的 value
- 使用 keys 和 in 检查一个 Dict 是否有特定的 key
- 使用 delete!() 函数删除 key
- 使用 pop!() 函数在返回值时删除键
- Symbol
- Symbol 实际上并不是一种数据结构。它是一种类型,并且其行为类似于字符串。
- string() 和 Symbol() 用于 Symbol 与字符串的转换
- Splat 运算符
- 展开运算符(类似 python 的解包)
- 文件系统
- Julia 中内置了处理不同操作系统差异 的功能。这一部分位于 Julia 核心库 Base 的 Filesystem 模块
- 确保代码能够运行在不同操作系统的文件系统 上。这可以通过 joinpath(),@__FILE__() 和 pkgdir() 函数轻松实现。
- Julia 标准库
- 使用特定的模块或函数前,需要将标准库模块导入到环境中
- 日期
- 随机数
- 先导入 Random 模块
- using Random: seed!
- rand()
- 支持无参数
- 获取多个随机数
- 在不同的区间抽样
- 给区间指定步长
- 可以组合和匹配参数
- 支持元素集构成的元组
- 也支持数组
- 还可以是 Dict
- randn() 从标准正态分布中生成
- 只接受 AbstractFloat 或 Complex 的子类型
- seed!
- 生成器要每次生成相同的随机数序列
- 在脚本开头调用 seed!() 是不够好的。为了避免 rand() 或 randn() 依赖全局变量,那么可以转而定义一个 seed!() 的实例,然后将它传递给 rand() 或 randn() 的第一个参数
- Downloads
- 从互联网上下载文件到本地,可以用通过 download() 函数实现