Julia常用包简介

  • Post author:
  • Post category:其他




第三方开发的Julia库(包),是Julia生态中极为重要的一部分。Julia包虽然目前没有Python那样丰富,但却极为快速地发展着。官方提供了包数量的统计趋势,见下图所示:


图D-1 Julia包发展趋势

由图可见,Julia包的发展非常之快。相信在不久的将来,其丰富性及多样性能够覆盖开发中的各种场景,并能够快速渗透到科学计算等领域。读者可在



https://pkg.julialang.org/



这个网站的近两千个包中寻找适合自己的包。

下面我们将列举一些常用包,关于它们的详细使用方法,请参阅官方文档。


Documenter.jl

这是一个由官方维护的包,专门用于将Julia代码中的注释系统(Docstrings)及其中的Markdown文件生成完整的说明文档。

该包提供的文档生成器,具备以下功能特点:

  • 支持Markdown语法
  • 开箱即用(Minimal Configuration)
  • 支持Julia 0.6及0.7-dev版本(截止书稿时)
  • 会对注释中标注的代码执行测试语句(Doctest)
  • 支持文档章节等方面的交叉引用
  • 支持LaTeX语法
  • 文档字符系统缺失与交叉引用错误的检查
  • 自动生成目录与文档索引
  • 使用Git自动构建与部署文档,并能推送到GitHub的文档库中

包Documenter.jl是已经注册的包,安装很简单,只需执行Pkg.add(“Documenter”)命令即可。该包会将代码库的Markdown文件及代码中以docstrings方式注释的文档系统解析合并为单一的内联(inter-linked)文档。


DataFrames.jl

在科学计算中往往需要综合多种库的优势,以构造强大的应用与分析系统,一个通用的数据结构便成为整合这些不同库的纽带,能够为跨库调用带来极大的便利,更是为生态的快速发展奠基了基础。

在Python语言中,有一个专门用于处理行列式或表格式(tabular)数据的结构,名为DataFrame,是科学计算库Pandas的重要组成部分,已成为很多Python第三方包支持的基本数据操作框架。

类似地,Julia语言的DataFrames库,正是意图建立这样一个基础的数据结构。通过Pkg.add(“DataFrames”)命令便可安装该包,此后使用using DataFrames即可将该包导入到开发者的名字空间中,使用DataFrames中的各种功能。

DataFrame类型能够表达表格式数据,并支持数据中存在缺失值。其内部是列存储的,每列是一个向量结构。在构建DataFrame对象时,可以同时列名,例如:

julia> using DataFrames

julia> df = DataFrame(A = 1:4, B = [“M”, “F”, “F”, “M”])

4×2 DataFrames.DataFrame

│ Row │ A │ B │

├───┼──┼──┤

│ 1   │ 1 │ M │

│ 2   │ 2 │ F │

│ 3   │ 3 │ F │

│ 4   │ 4 │ M │

在构造方法中,参数名即是列名,而参数值即是对应列的取值。例中的DataFrame对象有两列:第一列名为A,取1到4的整型;第二列名为B,值是字符串类型;而列Row是默认添加的行编号。

我们可以通过一些函数查看DataFrame对象的属性:

julia> size(df)   # 取得DataFrame对象的行与列数

(4, 2)

julia> size(df,1)  # 取得对象的行数

4

julia> size(df,2)  # 取得对象的列数

2

也可以通过describe()函数取得基本统计信息:

julia> describe(df)

A                               # 列名

Summary Stats:

Mean:           2.500000         # 均值

Minimum:       1.000000          # 最小值

1st Quartile:      1.750000         # 分位数

Median:          2.500000        # 中值

3rd Quartile:      3.250000         # 分位数

Maximum:       4.000000         # 最大值

Length:          4               # 行数

Type:            Int64           # 数据类型

B

Summary Stats:

Length:         4               # 行数

Type:           String           # 数据类型

Number Unique:  2               # 唯一值(去重后)的数量

当然,我们可以通过列名,提取出某列的向量:

julia> df[:A]

4-element Array{Int64,1}:

1

2

3

4

julia> df[:B]

4-element Array{String,1}:

“M”

“F”

“F”

“M”

需要注意的是,代码中使用列名时,需使用Symbol类型表达。


CSV.jl

简单的数据交换与存储,可采用CSV格式,这是一种常用的表格式数据,而包CSV.jl专为CSV文件的读写提供了支持。

通过Pkg.add(“CSV”)后,即可使用该包。该包非常简单,基本上就两个操作,read()和write()函数。我们下面仅以read()函数为例,介绍该包的使用。

函数read()会从指定的文件中加载csv格式的数据,并存储到指定的数据结构中,默认的结构为DataFrame类型,其原型为:

CSV.read(fullpath::Union{AbstractString,IO}, sink::Type{T}=DataFrame, args…; kwargs…)

CSV.read(fullpath::Union{AbstractString,IO}, sink::Data.Sink; kwargs…)

其中fullpath指定csv文件的绝对路径,或者是已经打开的某个IO对象。其中的Data.Sink是第三方包DataStreams.jl提供的类型,可参阅相关文档,这里以DataFrame类型为例。

假设有一个csv文件,其内容如下表,各列以英文逗号分隔:


表D-1 CSV文件示例内容



c1



c2



c3



1


7.2


abc



12


8.4


def



13


9.3


ghi

通过CSV包读取,便可将该csv文件的内容加载到一个DataFrame对象中,即:

julia> using CSV

julia> data = CSV.read(“d:/test.csv”)

3×3 DataFrames.DataFrame

│ Row │ c1 │ c2  │ c3   │

├───┼───┼──┼───┤

│ 1   │ 11 │ 7.2 │  abc │

│ 2   │ 12 │ 8.4 │  def │

│ 3   │ 13 │ 9.3 │  ghi │

之后,便可基于DataFrames包的功能进行各种后续操作,例如describe()查看基本情况:

julia> describe(data)

c1

Summary Stats:

Mean:           12.000000

Minimum:        11.000000

1st Quartile:   11.500000

Median:         12.000000

3rd Quartile:   12.500000

Maximum:        13.000000

Length:         3

Type:           Union{Int64, Missings.Missing}

Number Missing: 0

% Missing:      0.000000

c2

Summary Stats:

Mean:           8.300000

Minimum:        7.200000

1st Quartile:   7.800000

Median:         8.400000

3rd Quartile:   8.850000

Maximum:        9.300000

Length:         3

Type:           Union{Float64, Missings.Missing}

Number Missing: 0

% Missing:      0.000000

c3

Summary Stats:

Length:         3

Type:           Union{Missings.Missing, String}

Number Unique:  3

Number Missing: 0

% Missing:      0.000000

从例中可见,CSV能够自动识别出每列的数据类型.

假设上例中的数据有一个缺失值,并以N字符表示,如下表所示:


表D-2 有缺失值的CSV文件示例



c1



c2



c3



11


7.2


abc



12


N


def



13


9.3


ghi

在读取数据时,设置missingstring参数[

[1]

]为N,告知read()函数有缺失值:

julia> data = CSV.read(“d:/test.csv”; missingstring=”N”)

3×3 DataFrames.DataFrame

│ Row │ c1 │ c2     │ c3   │

├───┼──┼────┼───┤

│ 1   │ 11 │ 7.2     │  abc │

│ 2   │ 12 │ missing │  def │

│ 3   │ 13 │ 9.3     │  ghi │

可见,在获得的DataFrame中,列c2中的缺失值得到了正确的识别。

另外,通过read()函数的键值参数还可以告知csv的其他各种格式情况,以便在加载数据时能够成功处理。下面给出该函数的其他一些使用示例:

# 读取以空白符为分隔符的文件

CSV.read(file; delim=’ ‘)

# 自定义列名,适用于文件中没有提供表头的csv文件,但需要列名的数量与文件的列数一致

CSV.read(file; header=[“col1”, “col2”, “col3”])

# 自定义每列的数据类型,但必须与实际的数据匹配

CSV.read(file; types=[Int, Int, Float64])

# 自定义读取的文件行数,有助于提高解析速度,并可用于只读取所需的有限头部数据

CSV.read(file; rows=10000)


JSON.jl

在数据交换中,尤其是网络数据中,Json格式的使用非常频繁,Julia同样提供了一个简洁的库,用于处理这类格式的数据。

假设有个名为s的字符串变量,存储着Json数据,如下所示:

{

“a_number”: 5.0,

“an_array”: [“string”, 9],

“inner”: {

“value”: 3

}

}

在安装JSON包后,可以尝试将其解析到数据结构,语句非常简单:

julia> s = “{\”a_number\” : 5.0, \”an_array\” : [\”string\”, 9], \”inner\”: {\”value\”: 3}}”;

julia> j = JSON.parse(s)

Dict{String,Any} with 3 entries:

“an_array” => Any[“string”, 9]

“a_number” => 5.0

“inner”    => Dict{String,Any}(Pair{String,Any}(“value”, 3))

函数parse()会将s的内容分析出来,放在一个嵌套的Dict对象中,并会自动进行数据类型识别,然后就可以通过关键字进行层层提取了。

julia> j[“an_array”]

2-element Array{Any,1}:

“string”

9

julia> j[“inner”]

Dict{String,Any} with 1 entry:

“value” => 3

julia> j[“inner”][“value”]

3

反之,也可以将对象结构转换到Json字串,便于存储或传输:

julia> JSON.json(j)

“{\”an_array\”:[\”string\”,9],\”a_number\”:5.0,\”inner\”:{\”value\”:3}}”


Taro.jl

这是一个基于Apache Tika等库开发的用于从Word、Excel或PDF文件中提取内容的强大的库,其有以下几个功能点:

  • 能够从Word、Excel、PDF文件中提取原始的文本数据
  • 从Excel文件中将数据提取到DataFrame结构中
  • 以Julia语言读取Excel文件的API接口函数
  • 将采用XSL-FO布局的文件转换为PDF文件


Gadfly.jl

包Gadfly是Julia语言开发的绘图与可视化库,由Daniel C. Jones设计,现在由社区维护,其特点包括:

  • 相当于SVG、PNG、Postscript与PDF的图形渲染质量
  • 直观的、一致性的绘图接口设计
  • 可在IJulia中使用
  • 能够使用DataFrames.jl数据结构
  • 支持大量的绘图类型

Gadfly采用了一种被称为“图形语法(grammar of graphics)”的标准进行架构的设计,其在绘图命令(plot specification)提交后,会遵循内部的流水线进行渲染,得到最终的结果。

渲染流水线(rendering pipeline)会将绘图命令转为一个整体性的图形场景,包括坐标轴、颜色等导引元素(guides),及分层的点、线等图形元素(geometry)。每一层会包括数据源、图形元素(简称图元)、数据与图元的关联映射、应用于层次数据统计等部分。所有的层共享如下元素:坐标系(如笛卡尔坐标系、极坐标系等)、坐标轴的缩放(如重对数、半对数等)、图形场景统计及导引元素等。

一套完整的的绘制命令需要描述清楚这些共享的元素及各层的规格(specifications)。完整的渲染进程如图所示:


图D-2 Gadfly渲染流水线框架



ECharts.jl


ECharts是一款由百度前端技术部开发的,基于Javascript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。提供大量常用的数据可视化图表,底层基于

ZRender

(一个全新的轻量级canvas类库),创建了坐标系,图例,提示,工具箱等基础组件,并在此上构建出折线图(区域图)、柱状图(条状图)、散点图(气泡图)、饼图(环形图)、K线图、地图、力导向布局图以及和弦图,同时支持任意维度的堆积和多图表混合展现。


图D-3 Echarts框架图[



[2]


]

包ECharts.jl基于Julia语言对JavaScript的ECharts 4进行了封装,从而能在Julia中使用这个强大的图表库。在Pkg.add(“ECharts”)之后,即可通过using ECharts使用该包。

例如我们要绘制一个柱状图:

using ECharts

x = [“Monday”,”Tuesday”,”Wednesday”,”Thursday”,”Friday”,”Saturday”,”Sunday”]

y = [11, 11, 15, 13, 12, 13, 10]

bm = bar(x, hcat(0.95 .* y, 1.25 .* y, y))

则会获得下图:


图D-4 Echarts柱状图示例

也可以绘制金融当中常见的K线图:

using ECharts

dt = [“2016/08/26”, “2016/08/29”, “2016/08/30”, “2016/08/31”, “2016/09/01”, “2016/09/02”,

“2016/09/06”, “2016/09/07”, “2016/09/08”, “2016/09/09”, “2016/09/12”, “2016/09/13”,

“2016/09/14”, “2016/09/15”, “2016/09/16”, “2016/09/19”, “2016/09/20”, “2016/09/21”,

“2016/09/22”, “2016/09/23”, “2016/09/26”]

close_ = [12.38, 12.47, 12.55, 12.60, 12.44, 12.50, 12.67, 12.70, 12.73,

12.38, 12.70, 12.38, 12.14, 12.11, 12.11, 12.11, 12.00, 12.09, 12.18,

12.17, 12.01]

open_ = [12.47, 12.38, 12.46, 12.48, 12.66, 12.53, 12.49, 12.62, 12.50,

12.61, 12.32, 12.53, 12.18, 12.14, 12.05, 12.12, 12.09, 12.08, 12.17,

12.12, 12.12]

high_ = [12.55, 12.50, 12.56, 12.61, 12.72, 12.57, 12.67, 12.75, 12.75,

12.6850, 12.77, 12.68, 12.31, 12.18, 12.13, 12.33, 12.19, 12.11, 12.29,

12.22, 12.12]

low_ = [12.34, 12.38, 12.43, 12.48, 12.35, 12.46, 12.43, 12.62, 12.50,

12.38, 12.28, 12.33,12.11, 12.06, 12.01, 12.0586, 11.96, 12.01, 12.16,

12.12, 12.00]

c = candlestick(dt, open_, close_, low_, high_)

执行获得的图标如下所示:


图D-5 Echarts绘制K线图示例

利用ECharts.jl包,可以绘制更多的图表,读者可以根据官方文档获得更多的帮助。


QML.jl

在图像界面接口(Graphical User Interface,GUI)方面,QT是基于C++开发的跨平台框架,支持包括Windows、Linux、Android、WP、IOS等多种系统平台,是一个笔者非常欣赏的用C++语言开发的GUI套件,其简洁明了的接口和框架,使用起来非常的方便,而且界面控制也非常的容易。借助QT官方提供的QT Creator工具,更能够快速地设计出合用的交互界面。而且,QT不限于开发GUI,更适用于常见场景的应用开发,包括控制台工具、服务器、网络通讯等。该套件提供社区版,开发者只要遵循其协议,可免费使用。

在界面实现时,除了使用C++语言设计交互逻辑外,还可以使用一种类型JavaScript语言的名为QML的脚本语言进行界面设计,而在Julia中,包QML.jl即是通过CxxWrap.jl包提供了Qt5 QML的编程支持。

在采用Julia进行GUI编程时,还可以参看PySide.jl包、Qwt.jl包及Gtk.jl包。


JDBC.jl

数据库的操作在Julia中也非常方便,其中的JDBC.jl包提供了数据库访问的支持。

该包基于JavaCall.jl包的功能,通过Java的接口访问JDBC驱动。提供的API包括两种核心组件,一种是访问JDBC的直接接口,另一种是支持DataStreams.jl的Julia接口。

在使用该包前,需要安装好对应的JDBC,并配置了正确的路径,然后需先对JVM进行初始化,如下:

using JDBC

JDBC.usedriver(“/home/me/derby/derby.jar”)   # 路径指向驱动包

JDBC.init()      # 或JavaCall.init()

需要注意的是,在使用该包后,需要显式地进行资源释放:

JDBC.destroy()    # 或JavaCall.destroy()

另外,在https://github.com/JuliaDatabases中列出了更多关于数据库操作的Julia包,例如SQLite.jl包、ODBC.jl包、PostgreSQL.jl包、MySQL.jl包等。


Distributions.jl

概率分布在科学计算中常常遇到,无论是样本分析、概率表达等。包Distributions则在概率分布方面提供了很好的支持。其功能特点有:

  • 矩(包括均值、方差、 偏度、峰度等)的计算,还有熵及其他属性
  • 概率密度函数及其对数表达
  • 矩生成函数与特征函数
  • 样本采样或总体采样
  • 最大相似度估计

该包同时还支持多元统计分布、混合模型、假设检验及分布拟合等计算。



Distances.jl


这又是一个强大的包,提供了各种相似性度量函数的支持。所谓相似性度量,是在模式识别与机器学习中必然会用到的基础模块之一,用于评估两个特征向量的距离,即相似性程度。采用何种距离函数,不论是在聚类还是在分类中,都是需要认真考虑并慎重选择的。

该包在相似度计算的实现中,是进行了优化的,相比于粗糙地使用迭代的方式实现距离评估,有着很大的性能优势。有兴趣的,可在官方包中找到对应的Benchmark对比数据。

下面我们列出其支持的所有距离函数,在开发中可自行选择。关于这些距离函数的具体定义,也请读者能够自行找些资料,仔细研究下。


表D-3 Distances支持的距离算法


中文名


英文名

欧式距离

Euclidean Distance

平方欧式距离

Squared Euclidean Distance

街区距离

Cityblock Distance

杰卡德距离

Jaccard Distance

Rogers-Tanimoto距离

Rogers-Tanimoto Distance

切比雪夫距离

Chebyshev Distance

闵可夫斯基距离

Minkowski Distance

海明距离

Hamming Distance

余弦相似度

Cosine Distance

相关系数

Correlation distance

卡方距离

Chi-square distance

KL散度

Kullback-Leibler divergence

标准化KL散度

Generalized Kullback-Leibler divergence

瑞利散度

Rényi divergence

JS散度

Jensen-Shannon divergence

马氏距离

Mahalanobis distance

平方马氏距离

Squared Mahalanobis distance

巴氏距离

Bhattacharyya distance

黑林格距离

Hellinger distance

半正矢距离

Haversine distance

平均绝对偏差

Mean absolute deviation

均方差

Mean squared deviation

均方根偏差

Root mean squared deviation

标准化的均方根偏差

Normalized root mean squared deviation

布雷柯蒂斯相异度

Bray-Curtis dissimilarity

另外,这些相似性度量,在包中的具体实现还会有很多的变体,有着更为丰富的选择。笔者提醒,在使用这些距离函数时,最好能很清楚这些函数的定义方式,最为重要的一点是,这些距离函数的计算结果,是越大越表示相似,还是越小越表示相似。


TensorFlow.jl

该包是对Google开发的深度学习库TensorFlow的封装,只需执行

Pkg.add(“TensorFlow”)

即可安装该包。若要在Linux上支持GPU加速,可设置环境变量TF_USE_GPU为1,然后重新编译,即:

ENV[“TF_USE_GPU”] = “1”

Pkg.build(“TensorFlow”)

该包现已支持的功能有:

  • 所有基本的一元及二元数学函数或运算符;
  • 最常用的神经网络操作,包括卷积、GRU版的循环神经网络及dropout等;
  • 神经网络训练模块,例如AdamOptimizer等;
  • 基本的图像加载及缩放操作;
  • 控制逻辑操作;
  • PyBoard图可视化。


Mocha.jl

包Mocha是Julia语言实现的深度学习框架,类似于C++中的Caffe库。Mocha高效地实现了常见的随机梯度优化和通用层,通过无监督的自编码器的学习方式,可用于训练深度神经网络(Deep Neural Networks,DNN)和卷积神经网络(Convolutional Neural Networks,CNN)。Mocha的特点有:

  • 模块化的架构。Mocha有着清晰的组织结构,而且各个组件间是低耦合的(isolated)。这些模块包括网络层、激励函数、优化过程、正则化函数、初始化函数等。内置的组件已足够用于典型的DNN或CNN应用,而开发者更可在其基础上进行类型扩展。
  • 高层接口。借助Julia语言强大的表达能力及迅速发展的开源生态,在Mocha中使用DNN等功能会很容易、自然。可通过提供的图像分类案例进行方便的学习。
  • 可移植及高性能。Mocha因为基于Julia语言,故可运行于任何支持Julia语言的平台上,而且这种移植性对于开发者来说是透明的。基于Julia语言JIT编译器与各种内置的性能函数,可以很方便、高效地进行算法的原型设计,并能够直接获得性能评估。而且,在C++编译器可用时,原生扩展后端打开后能够比纯粹的Julia后台快2到3倍。

Mocha提供的GPU后台使用的是NVidia®的cuDNN库,cuBLAS库及定制的CUDA内核,提供了高性能的计算能力。采用GPU加速后,在现代GPU设备中,特别是在大型模型中,能够获得20到30倍的速度提升。

  • 兼容性。借助专用于科学数据存储的HDF5格式,在Mocha用其存储数据集及模型的快照,从而能够很容易地与Matlab、Python(Numpy)及其他已存在的计算库进行数据交换。Mocha同样提供了从Caffe中导入训练模型快照的工具,开发者可以充分利用不同库的优势。
  • 可靠性(Correctness)。Mocha中的每个组件都经过了充分的测试,其正确性与可靠性是保证的。
  • 开源开放。Mocha采用的MIT(Expat)许可证,其源代码是开源的,开发者可以方便地进行学习,并可自行扩展。

若要安装Mocha库,只需在Julia的REPL中,运行命令:

Pkg.add(“Mocha”)

即可。


[[1]] 旧版CSV包中使用键值参数null指定缺失值的标识字符串,但新版中已弃用,被missingstring代替。

[[2]] 图片来自https://www.oschina.net/p/echarts



版权声明:本文为conkty原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。