「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。目下、データ分析・語学に力点を置いています。

MENU

Juliaを使うときのTipsをまとめる(その09/X)

 \mathrm{Julia}を使うのに、今一度

で使い方を整理する。

前回

power-of-awareness.com

注意

 参照文献はかなり古い(2019年)ため、現在のバージョンでは動作しない関数などが多いとの評判がある。そこでそういった齟齬があった場合は随時コメントする。なお筆者の環境は、

アプリケーション バージョン
\mathrm{Julia} 1.8.0
\mathrm{Jupyter} \mathrm{Notebook} 6.5.2

である。

2. Juliaによるデータエンジニアリング

2.7 オブジェクトのシリアライズ

 \mathrm{Julia}にもオブジェクト・シリアライズが用意されている。シリアライズとは、任意のオブジェクトのバイト列表現を取得することで、取得したバイト列はディスクに直接書き込んだり、ネットワークを通じて送信したりすることができる。シリアライズは普通、短期的にデータを保持するために用いる。

  • 組み込み型

     時間面でもディスク空間面でも最も効率が良い。しかし様々な環境で動作させる場合や異なるハードウェア・アーキテクチャで実行する場合には望ましくない
##################################
### データをシリアライズする① ###
##################################

using Serialization

# 任意のJuliaオブジェクトをストリームに書き込むことができる
x = 1:5
open(f -> serialize(f,x), "x.jls", "w")

# deserializeも同様にする
y = open(deserialize, "x.jls")

# オブジェクトの中身を確認する
dump(y)

# ストリームに複数のオブジェクトを記録する
open("data.jls", "w") do f
    serialize(f, Array{Int8}([1, 2, 4]))
    serialize(f, Dict{Int64,String}(1=>"a", 2=>"b"))
end

# 結果をREPLから確認する
f = open("data.jls","r")
println(deserialize(f))

println(deserialize(f))

close(f)
  • JLD2形式

     長期間の保存や異なるプラットフォーム間でもデータ交換に適している。
##################################
### データをシリアライズする② ###
##################################

using JLD2
using FileIO

x1 = 1:5
x2 = rand(3)
file = File(format"JLD2", "(適当なパスを設定)/myfile.jld2") # 
save(file, "x1", x1, "x2", x2)

data = load(file)

dump(data["x1"])
  • BSON.jlパッケージ

     長期間のデータ保存に適している。
##################################
### データをシリアライズする③ ###
##################################

using BSON

x = 1:5
d = Dict{Int64, String}(1=>"a", 2=>"b")
e = 5+3im

f = open("data.bson", "w")
bson(f, Dict("x" => x, "d" => d))
bson(f, Dict("e" => e))
close(f)

f = open("data.bson", "r")
BSON.load(f)
BSON.load(f)

close(f)

分散高性能計算では、ディスクI/OやネットワークI/Oの際にデータ圧縮を行なった方が効率が良い場合がある。この場合、データをシリアライズすることでストリームに書き込む前に圧縮することを検討した方が良い。\mathrm{JLD2}モジュールにはデータ圧縮機構が組み込まれている。

2.8 Microsoft Excelファイルを読み書きする

 \mathrm{Python}のパッケージを呼び出して、\mathrm{Excel}ファイルを操作する。また\mathrm{Julia}のパッケージ\mathrm{XLSX.jl}を用いてみる。

  • \mathrm{PyCall}\mathrm{openpyxl}を呼び出す方法
###################################################
### Pythonモジュールを用いてExcelにアクセスする ###
###################################################

# 生成した乱数をExcelファイルに保存する
using Conda
using PyCall
using Dates
using Random

xl = pyimport("openpyxl")

# Workbookオブジェクトを生成する
wb = xl.Workbook() # ワークブックの生成
ws = wb.active      # 生成したワークブックのワークシートを選択

# ワークシートのセルに書き込む
ws.cell(1,1,"生成したデータ:")
ws.cell(2,1,Dates.now())

# 
Random.seed!(0)
dat = rand(3,5)
for i in 1:size(dat)[1]
    ws.append((dat[i, :]...,))
end

# 作成したワークブックを保存する
wb.save(".../sample1.xlsx") # ...部分には適切なパスを決めて入力する

### 今度はExcelファイルの読み込み
# 上で作成したファイルを読み込む

# Excelファイルを開き、シートを選択する
wb = xl.load_workbook(filename = ".../sample1.xlsx")
ws = wb.active

# ワークシートから、セルの内容を読みだす
println(ws.cell(1,1).value,"\n", ws.cell(2,1).value)

# 日付が含まれたセルの値は自動的にJuliaのDate型に変換されている
println("2行1列目セルを読み込んだ値の型:",typeof(ws.cell(2,1).value))
    
# 存在しないセルはnothing
println(ws.cell(20, 210) == nothing)

# 行や列に対する繰り返し
# *現在のVerではデータの無いセル(行)も延々と参照されるようでかなりループが続くので注意
using Printf
for row in ws.rows
    for cell in row
        print("|")
        if typeof(cell.value) <: Number
            @printf("%.3f", cell.value)
        else
            show(cell.value)
        end
    end
    println("|")
end

wb.close()
  • \mathrm{Julia.jl}を用いる方法
####################################################
### Juliaのパッケージを用いてExcelにアクセスする ###
####################################################

using XLSX
using Dates
using Random

row_num = 3
col_num = 5

# ワークブックを生成する
XLSX.openxlsx(".../sample2.xlsx", mode = "w") do xf
    sheet = xf[1]
    XLSX.rename!(sheet, "SheetName")
    sheet["A1"] = "生成したデータ:"
    sheet["A2"] = Dates.now()
    dat = rand(row_num,col_num)
    for row in 1:row_num
        for col in 1:col_num
            XLSX.setdata!(sheet, XLSX.CellRef(2+row, col), rand())
        end
    end
end

# ワークブックをロードする
wb = XLSX.readxlsx(".../sample2.xlsx")

sheetname = XLSX.sheetnames(wb)[1]
ws = wb[sheetname]

# ワークシートから使用可能なセルに関する情報を取得し、そのセルのデータを読み取る
dim = ws.dimension

println(ws[dim])

XLSX.close(wb)
 
    
### XLSX.jlにはDataFrameオブジェクトを操作する便利な機能がある
using DataFrames

# 書き込みたい値をデータフレームとして準備する
df1 = DataFrame(a=[1,2,3], b= [4,5,6])
df2 = DataFrame(x1=[1,2,3], x2=["A","B","C"])

# 作成したデータフレームをExcelファイルに書き込む
XLSX.writetable(".../sample3.xlsx",
sheetName1 = (DataFrames.eachcol(df1), DataFrames.names(df1)),
sheetName2 = (DataFrames.eachcol(df2), DataFrames.names(df2)))
プライバシーポリシー お問い合わせ