裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

Julia で データフレームの入出力

2021年02月03日 | ブログラミング

== https://csv.juliadata.org/stable/#Getting-Started

== ファイルからデータフレームへの読み込み

以下のような内容を持つ small.csv ファイルを入力対象とする。

julia> run(`cat small.csv`)
a, b, c
1, 0.1, 34
2, 1, 54
3, 10, 0.4
4, 99, 554

julia> run(`cat small2.csv`)
a, 0.1, 34
b, 1, 54
c, 10, 0.4
d, 99, 554

csv ファイルをデータフレームに読み込むのは,以下のようにするのが一番簡単である。

julia> using CSV, DataFrames
julia> df = CSV.read("small.csv", DataFrame)
4×3 DataFrame
 Row │ a       b        c      
     │ Int64  Float64  Float64 
─────┼─────────────────────────
   1 │     1      0.1     34.0
   2 │     2      1.0     54.0
   3 │     3     10.0      0.4
   4 │     4     99.0    554.0

== 引数

header=整数
  列名の定義について指定する。省略されている場合は,適当に解釈される。
  列名が何行目に定義されているかを指定する。
  デフォルトでは header=1。
  2 以上の値が指定されたときはそれまでの行は読み飛ばされる。
  また,列名の指定行のすぐ後からデータが始まると解釈されるので,
  もし読み飛ばすべき行があるならば,skipto, datarow でデータ開始行を指定する。
  df = CSV.read("small.csv", DataFrame, header=0, skipto=2)
header=0 もしくは header=false
  列名を持たないファイルの場合は,列名を自動生成することができる。
  df = CSV.read("small2.csv", DataFrame, header=0)
header=["ab", "cd", ...]
  文字列ベクトルで列名定義
  df = CSV.read("small2.csv", DataFrame, header=["a1", "b1", "c1"])
header=[:ab, :cd, ...]
  シンボルベクトルで列名定義
  df = CSV.read("small2.csv", DataFrame, header=[:a, :b, :c]])
normalizenames=false
  列名の正規化をする
datarow
  データが始まる行番号
skipto
  データが始まる行番号 datarow と同じ
footerskip
  データの最後の何行を読み飛ばすかを指定
limit
  入力行数の制限
transpose=false
  行と列を転置して入力
comment
  指定した文字列から始まる行を(コメント行として)読み飛ばす
ignoreemptylines=true
  空行を読み飛ばす
select
  選択する行をベクトルで指定する
  select=[1, 3] 列番号で指定
  select=[:a, :c] 列シンボルで指定
  select=["a", "c"] 列名で指定
  select=[true, false, true] 論理値で指定
  select=(i, nm) -> i in (1, 3) ラムダ式(無名関数)で指定
drop
  選択しない行をベクトルで指定する(select の逆)
missingstrings, missingstring
  欠損値
  missingstring="-999"
  missingstrings=["-999", "NA"]
delim=','
  データのデリミター
  最初の 10 行を見て,',', '\t', ' ', '|', ';', ':' のどれかをデリミターと解釈する
  delim="@@@" のように文字列も使える
ignorerepeated=false
  連続するデリミタを無視するか
  複数の空白で桁位置を揃えて入力されたファイルを読むときなどに,
  delim=' ', ignorerepeated=true を指定すればよい。
quotechar='"'
  文字列をくくる引用符
escapechar='"'
  引用符のエスケープ文字
dateformat
  日付,時間のフォーマットを示す文字列
  dateformat="yyyy/mm/dd" など
dateformats
  日付,時間のフォーマットを辞書型で示す
decimal='.'
  小数点を表す文字
truestrings=["T", "TRUE"]
  true の他に真値を表す文字列の定義
falsestrings=["F", "FALSE"]
  false の他に真値を表す文字列の定義
type
  ファイル全体に共通する唯一のデータ型
  項目全てをここで指定した型として読む
  実数データ行列を読むときに type=Float64 のように指定する
types
  列ごとのデータ型
  ベクトルで与える場合は,全ての列について定義する
  types=Dict(3 => Int)
  types=Dict(:col3 => Int)
  types=Dict("col3" => Float64)
  types=[Int, Float64, String]
typemap
  特定の型の入力値を別の型として読み込む
  型のマッピング Dict(Float64=>String) のように指定
  typemap=Dict(Int => String)
  types=Dict(:zipcode => String)
pool
lazystrings=false
strict=false
  不正な値は警告して missing にする
silencewarnings=false
  strict=false のとき,不正な値の警告はしない
maxwarnings=100
  警告を表示する最高回数

== エンコーディングの違うファイルを読む

Windows で作られた日本語を含むファイルは,以下のようにして読む(shift_jis などではなく,cp932 を指定する)。
他にサポートされているエンコーディングは encodings() で参照できる。

julia> using StringEncodings
julia> CSV.File(open(read, "cp932.csv", enc"cp932")) |> DataFrame
2×3 DataFrame
 Row │ 日本語  ファイル  数値  
     │ Int64   Int64     Int64 
─────┼─────────────────────────
   1 │      1         2      3
   2 │      4         5      6

== gzip ファイルを読む

以下のようにして作られた gzip ファイルを読む。

読み込み法を示すためのテストデータの作成

julia> using CSV, DataFrames, CodecZlib, Mmap
julia> a = DataFrame(a = 1:3)
3×1 DataFrame
 Row │ a     
     │ Int64 
─────┼───────
   1 │     1
   2 │     2
   3 │     3

julia> CSV.write("a.csv", a)
"a.csv"

julia> run(`gzip a.csv`) # a.csv.gz ができる
a.csv.gz already exists -- do you wish to overwrite (y or n)? y
Process(`gzip a.csv`, ProcessExited(0))

a.csv.gz を読む

julia> a_copy = CSV.File(transcode(GzipDecompressor, Mmap.mmap("a.csv.gz"))) |> DataFrame
3×1 DataFrame
 Row │ a     
     │ Int64 
─────┼───────
   1 │     1
   2 │     2
   3 │     3

julia> a == a_copy # 同じであることを確認
true

== zip ファイルを読む

読み込み例を示すためのテスト用のファイルを作る

julia> using ZipFile, CSV, DataFrames
julia> a = DataFrame(a = 1:3)
3×1 DataFrame
 Row │ a     
     │ Int64 
─────┼───────
   1 │     1
   2 │     2
   3 │     3

julia> CSV.write("a.csv", a)
"a.csv"
julia> run(`zip a.zip a.csv`) # a.zip ファイルができる

updating: a.csv (stored 0%)
Process(`zip a.zip a.csv`, ProcessExited(0))

a.zip というファイルを読む

julia> z = ZipFile.Reader("a.zip")
ZipFile.Reader for IOStream() containing 1 files:

uncompressedsize method  mtime            name
----------------------------------------------
               8 Store   2021-02-03 15-55 a.csv

まだ続く

julia> a_file_in_zip = filter(x->x.name == "a.csv", z.files)[1]
ZipFile.ReadableFile(name=a.csv, method=Store, uncompresssedsize=8, compressedsize=8, mtime=1.612335328e9)

julia> a_copy = CSV.File(read(a_file_in_zip)) |> DataFrame
3×1 DataFrame
 Row │ a     
     │ Int64 
─────┼───────
   1 │     1
   2 │     2
   3 │     3


== データフレームを csv ファイルに書き出す

CSV.write(ファイル, table)
table |> CSV.write(ファイル)

引数

bufsize=2^22
  バッファーサイズ
delim=','
  デリミター
quotechar='"'
  引用符
escapechar='"'
  引用符のエスケープ文字
missingstring=""
  missing を表す文字列
dateformat
  dateformat="yyyy/mm/dd" など append=false
  既存のファイルに書き足すかどうか
writeheader=!append
  列名を出力するか
header
  使用する列名のリスト
newline='\n'
  改行文字
quotestrings=false
  文字列を引用符で囲むかどうか
decimal='.'
  小数点として使用する文字
transform
bom=false
partition=false

== その他の基礎的な入力方方法

read(``small.csv'') は バイト列を返す。

julia> read("small.csv")[1:5]
5-element Array{UInt8,1}:
 0x61
 0x2c
 0x20
 0x62
 0x2c

CSV.File は CSV.File オブジェクトを返す。

julia> CSV.File("small.csv")
4-element CSV.File{false}:
 CSV.Row: (a = 1,  b = 0.1,  c = 34.0)
 CSV.Row: (a = 2,  b = 1.0,  c = 54.0)
 CSV.Row: (a = 3,  b = 10.0,  c = 0.4)
 CSV.Row: (a = 4,  b = 99.0,  c = 554.0)

julia> CSV.File(read("small.csv")) # 前述の CSV.File("small.csv")  と同じ
4-element CSV.File{false}:
 CSV.Row: (a = 1,  b = 0.1,  c = 34.0)
 CSV.Row: (a = 2,  b = 1.0,  c = 54.0)
 CSV.Row: (a = 3,  b = 10.0,  c = 0.4)
 CSV.Row: (a = 4,  b = 99.0,  c = 554.0)

julia> read("small.csv") |> CSV.File # CSV.File("small.csv") と同じ
4-element CSV.File{false}:
 CSV.Row: (a = 1,  b = 0.1,  c = 34.0)
 CSV.Row: (a = 2,  b = 1.0,  c = 54.0)
 CSV.Row: (a = 3,  b = 10.0,  c = 0.4)
 CSV.Row: (a = 4,  b = 99.0,  c = 554.0)

以上の 3 通りの後に,さらに DataFrame
へパイプを繋げば,データフレームとして読まれる。

julia> CSV.File("small.csv") |> DataFrame
4×3 DataFrame
 Row │ a       b        c      
     │ Int64  Float64  Float64 
─────┼─────────────────────────
   1 │     1      0.1     34.0
   2 │     2      1.0     54.0
   3 │     3     10.0      0.4
   4 │     4     99.0    554.0

julia> CSV.File(read("small.csv"))  |> DataFrame
4×3 DataFrame
 Row │ a       b        c      
     │ Int64  Float64  Float64 
─────┼─────────────────────────
   1 │     1      0.1     34.0
   2 │     2      1.0     54.0
   3 │     3     10.0      0.4
   4 │     4     99.0    554.0

julia> read("small.csv") |> CSV.File |> DataFrame
4×3 DataFrame
 Row │ a       b        c      
     │ Int64  Float64  Float64 
─────┼─────────────────────────
   1 │     1      0.1     34.0
   2 │     2      1.0     54.0
   3 │     3     10.0      0.4
   4 │     4     99.0    554.0

CSV.Rows は行イテレータを返すが,特に指定しなければ全て文字列として読まれる。

julia> CSV.Rows("small.csv")
CSV.Rows("small.csv"):
Size: 3
Tables.Schema:
 :a            Union{Missing, String}
 Symbol(" b")  Union{Missing, String}
 Symbol(" c")  Union{Missing, String}

julia> CSV.Rows(read("small.csv"))
CSV.Rows(""):
Size: 3
Tables.Schema:
 :a            Union{Missing, String}
 Symbol(" b")  Union{Missing, String}
 Symbol(" c")  Union{Missing, String}

julia> read("small.csv") |> CSV.Rows
CSV.Rows(""):
Size: 3
Tables.Schema:
 :a            Union{Missing, String}
 Symbol(" b")  Union{Missing, String}
 Symbol(" c")  Union{Missing, String}

以上の 3 通りの後に,さらに DataFrame
へパイプを繋げば,データフレームとして読まれる。ただし,特に指定しなければ全て文字列として読まれる。

julia> CSV.Rows("small.csv") |> DataFrame
4×3 DataFrame
 Row │ a         b        c      
     │ String?  String?  String? 
─────┼───────────────────────────
   1 │ 1         0.1      34
   2 │ 2         1        54
   3 │ 3         10       0.4
   4 │ 4         99       554

julia> CSV.Rows(read("small.csv")) |> DataFrame
4×3 DataFrame
 Row │ a         b        c      
     │ String?  String?  String? 
─────┼───────────────────────────
   1 │ 1         0.1      34
   2 │ 2         1        54
   3 │ 3         10       0.4
   4 │ 4         99       554

julia> read("small.csv") |> CSV.Rows |> DataFrame
4×3 DataFrame
 Row │ a         b        c      
     │ String?  String?  String? 
─────┼───────────────────────────
   1 │ 1         0.1      34
   2 │ 2         1        54
   3 │ 3         10       0.4
   4 │ 4         99       554

列の内容に従ってデータフレームに読み込むには,CSV.File(ファイル名) |> DataFrame が簡単であろう。
読み取ったデータフレームは,変数に代入する。

julia> df = CSV.File("small.csv") |> DataFrame
4×3 DataFrame
 Row │ a       b        c      
     │ Int64  Float64  Float64 
─────┼─────────────────────────
   1 │     1      0.1     34.0
   2 │     2      1.0     54.0
   3 │     3     10.0      0.4
   4 │     4     99.0    554.0

以下のようにすればよさそうに思うかも知れないが,パイプは使えない。
CSV.File(``small.csv'') |> DataFrame |> df

データフレームからさらにパイプを繋いで配列にするときには以下のようにすればよい。
配列の場合は,全ての要素が同じ型に変換されることに注意。

julia> M = CSV.File("small.csv") |> DataFrame |> Matrix
4×3 Array{Float64,2}:
 1.0   0.1   34.0
 2.0   1.0   54.0
 3.0  10.0    0.4
 4.0  99.0  554.0

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« Juliaでcsvに読み書き | トップ | しんきろう! »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事