Julia で CSV ファイルを読む。あるいは,データフレームを使う。
まずは,CSV と DataFrames パッケージのインストール。
(@v1.5) pkg> add CSV, DataFrames
Updating registry at `~/.julia/registries/General`
######################################################################## 100.0%
Resolving package versions...
Installed PooledArrays ─── v0.5.3
Installed SentinelArrays ─ v1.2.16
Installed CSV ──────────── v0.8.2
Updating `~/.julia/environments/v1.5/Project.toml`
[336ed68f] + CSV v0.8.2
Updating `~/.julia/environments/v1.5/Manifest.toml`
[336ed68f] + CSV v0.8.2
[2dfb63ee] + PooledArrays v0.5.3
[91c51154] + SentinelArrays v1.2.16
Resolving package versions...
Installed InvertedIndices ─── v1.0.0
Installed StructTypes ─────── v1.2.1
Installed CategoricalArrays ─ v0.9.0
Installed DataFrames ──────── v0.22.2
Installed PrettyTables ────── v0.10.1
Updating `~/.julia/environments/v1.5/Project.toml`
[a93c6f00] + DataFrames v0.22.2
Updating `~/.julia/environments/v1.5/Manifest.toml`
[324d7699] + CategoricalArrays v0.9.0
[a93c6f00] + DataFrames v0.22.2
[41ab1584] + InvertedIndices v1.0.0
[08abe8d2] + PrettyTables v0.10.1
[856f2bd8] + StructTypes v1.2.1
[9fa8497b] + Future
そして,using CSV, DataFrames。初回はコンパイルを伴うので,少しばかり時間がかかる。
julia> using CSV, DataFrames
[ Info: Precompiling CSV [336ed68f-0bac-5ca0-87d4-7b16caf5d00b]
[ Info: Precompiling DataFrames [a93c6f00-e57d-5684-b7b6-d8193f3e46c0]
読み込むデータがどこにあるか,確認しておくこと。
必要なら working directory を変更しておく。
julia> cd("/Users/foor/bar/")
julia> @time df = CSV.read("test.csv", DataFrame);
9.007682 seconds (49.06 k allocations: 1.257 GiB, 1.77% gc time)
実行時間測定のために @time を付けたが,必要なければ取る。
対話モードでやるときは,最後の ';' を付けておく方がいいかもしれない。
R の data.table::fread() では 5.027 sec. であったので,ちょっと負けるなあ。
でも,Python でも 28.793 sec. なので,よしとしよう。
julia> row, col = size(df) # データフレームのサイズ
(100000, 1500)
データフレームの最初の方の確認
julia> first(df, 5)
5×1500 DataFrame
Row │ X1 X2 X3 X4 ⋯
│ Float64 Float64 Float64 Float64
────┼──────────────────────────────────────
1 │ 51.26 44.35 38.61 36.61
2 │ 41.03 59.43 48.48 59.44
3 │ 61.89 29.32 64.51 51.07
4 │ 56.88 59.77 49.92 48.76
5 │ 69.43 56.75 65.3 47.28 ⋯
1488 columns omitted
データフレームの最後の方の確認
julia> last(df, 5)
5×1500 DataFrame
Row │ X1 X2 X3 X4 ⋯
│ Float64 Float64 Float64 Float64
────┼──────────────────────────────────────
1 │ 48.05 58.57 44.79 56.38
2 │ 79.41 41.44 53.72 52.31
3 │ 61.82 48.27 60.91 36.46
4 │ 49.19 24.26 49.97 44.7
5 │ 51.66 66.37 56.99 55.78 ⋯
1488 columns omitted
1 列目(変数名: "X1") の指定法
julia> sum(df[!, 1]) # 列番号で指定
5.004236609999999e6
julia> sum(df[!, "X1"]) # 変数名で指定 その1 df[!, 1],df[!, :1] も同じ
5.004236609999999e6
julia> sum(df.X1) # 変数名で指定 その2 df.X1 でも同じ
5.004236609999999e6
df[!, [:X1]] と df[:, [:X1]] はデータフレームだが,df[!, :X1] と df[:, :X1] はベクトル
df[!, "X1"] はコピーを作らない,df[:, "X1"] はコピーを作る
julia> df[!, "X1"] === df[:, "X1"] # === は同一かどうか(メモリー上で同じ位置にあるもの)
false
julia> df[!, "X1"] == df[:, "X1"] # == は等しいかどうか
true
julia> df[:, [:X2, :X5]]
100000×2 DataFrame
Row │ X2 X5
│ Float64 Float64
────────┼──────────────────
1 │ 44.35 54.22
2 │ 59.43 44.9
3 │ 29.32 34.25
4 │ 59.77 43.93
以上の他にも何種類かある。
行の抽出
julia> df2 = df[15:36, :]
22×1500 DataFrame
Row │ X1 X2 X3 ⋯
│ Float64 Float64 Float64 ⋯
────┼───────────────────────────────
1 │ 58.78 39.62 72.1 ⋯
2 │ 46.84 59.54 46.05 ⋯
:
22 │ 69.09 54.01 54.76
julia> size(df2)
(22, 1500)
抽出と同時に並べ替えもできる。
julia> df3 = df[[5, 2, 7], :]
3×1500 DataFrame
Row │ X1 X2 X3
│ Float64 Float64 Float64
────┼───────────────────────────
1 │ 69.43 56.75 65.3 ⋯
2 │ 41.03 59.43 48.48
3 │ 44.68 59.1 51.65
julia> size(df3)
(3, 1500)
列の抽出
julia> df4 = df[:, ["X1", "X5", "X2"]]
100000×3 DataFrame
Row │ X1 X5 X2
│ Float64 Float64 Float64
────────┼───────────────────────────
1 │ 51.26 54.22 44.35
2 │ 41.03 44.9 59.43
3 │ 61.89 34.25 29.32
4 │ 56.88 43.93 59.77
:
julia> size(df4)
(100000, 3)
行と列を同時に抽出
上の応用。
julia> df5 = df[[10, 5, 3], ["X1", "X5", "X2"]]
3×3 DataFrame
Row │ X1 X5 X2
│ Float64 Float64 Float64
─────┼───────────────────────────
1 │ 49.09 56.05 45.22
2 │ 69.43 45.76 56.75
3 │ 61.89 34.25 29.32
julia> size(df5)
(3, 3)
条件を満たす行の抽出
julia> df6 = df[df.X1 .> 87, ["X2", "X6", "X9"]] # > 前のピリオドを忘れないように
9×3 DataFrame
Row │ X2 X6 X9
│ Float64 Float64 Float64
─────┼───────────────────────────
1 │ 55.27 59.61 64.16
2 │ 38.27 38.72 41.42
3 │ 38.24 53.88 29.97
該当セルへの代入
行と列の指定法がわかれば,該当セルへの代入も同じように行えることがわかる。
julia> df7[1, 2] = 99999
99999
julia> df7
4×4 DataFrame
Row │ X6 X4 X1 X2
│ Float64 Float64 Float64 Float64
─────┼───────────────────────────────────
1 │ 38.72 99999.0 90.19 38.27
2 │ 49.75 49.8 89.25 64.74
3 │ 70.82 24.25 89.77 42.46
4 │ 34.49 54.26 92.58 55.82
列全部を代入対象とすることもできる。'.=' に注意。
julia> df7[!, 1] .= 77777
4-element Array{Int64,1}:
77777
77777
77777
77777
julia> df7
4×4 DataFrame
Row │ X6 X4 X1 X2
│ Int64 Float64 Float64 Float64
─────┼───────────────────────────────────
1 │ 77777 99999.0 90.19 38.27
2 │ 77777 49.8 89.25 64.74
3 │ 77777 24.25 89.77 42.46
4 │ 77777 54.26 92.58 55.82
並べ替え(ソート)
列を基準としてソートする。
julia> df8 = CSV.sort(df7, :X1)
4×4 DataFrame
Row │ X6 X4 X1 X2
│ Int64 Float64 Float64 Float64
─────┼───────────────────────────────────
1 │ 77777 49.8 89.25 64.74
2 │ 77777 24.25 89.77 42.46
3 │ 77777 99999.0 90.19 38.27
4 │ 77777 54.26 92.58 55.82