LoginSignup
11
11

More than 5 years have passed since last update.

JuliaでCSVを作成・更新してみた

Last updated at Posted at 2019-03-12

この記事について

JuliaでHTMLからデータを引っ張ってきて保存しようとした際に、CSV(というかDataFrame)の使い方がわからなかったので、まとめてみました。
あとCSV(というかDataFrame)の操作に関する日本語記事がなかなか見つからなかったので記事にしてみることにしました。

作業環境

Julia 1.0

使用したパッケージ

CSV
DataFrames

コーディング

簡単なCSVファイルの読み込み

まずはCSVファイルを読み込んでみます。

sampleCSV.csv
"商品名","値段","在庫"
"トマト",100,50
"トウモロコシ",150,20
"スイカ",200,30

最初の行はヘッダーで、残りはデータ行です。
これを読み込んで出力してみます。

TestCSV.jl
using CSV
using DataFrames

df = CSV.read("sampleCSV.csv", header=true, delim=',')
@show df

簡単に読み込んで出力するだけのソースコードです。
実行結果は以下の通りです。

3×3 DataFrames.DataFrame
│ Row │ 商品名       │ 値段   │ 在庫   │
│     │ String⍰      │ Int64⍰ │ Int64⍰ │
├─────┼──────────────┼────────┼────────┤
│ 1   │ トマト       │ 100    │ 50     │
│ 2   │ トウモロコシ │ 150    │ 20     │
│ 3   │ スイカ       │ 200    │ 30     │
DataFrames.DataFrame

DataFrame型をちょっと見てみる

DataFrameのスタートガイドページ
DataFrameの中身は行列と同じように後に[x]というように記述すると値を取得することが出来ます(xは任意の値)。
ただ、私の混乱したことが取得してくる値です。

DataFrameの動き
>>df
3×3 DataFrames.DataFrame
 Row  商品名        値段    在庫   
      String       Int64  Int64 
├─────┼──────────────┼────────┼────────┤
 1    トマト        100     50     
 2    トウモロコシ  150     20     
 3    スイカ        200     30     
>>df[1]
3-element Array{Union{Missing, String},1}:
 "トマト"
 "トウモロコシ"
 "スイカ"

1行目が取得されるのではなく1列目が取得されます。
CSVでは行よりも列を取得することが多いからじゃないかなと思いつつ、慣れていくしかなさそうです。

内容を変更して保存してみる

内容の更新

在庫の数を増やしてみます。

更新
>>df[3] = df[3] * 10
3-element Array{Int64,1}:
 500
 200
 300
>>df
3×3 DataFrames.DataFrame
 Row  商品名        値段    在庫  
      String       Int64  Int64 
├─────┼──────────────┼────────┼───────┤
 1    トマト        100     500   
 2    トウモロコシ  150     200   
 3    スイカ        200     300   

列単位で取得してこれるので、こういった更新は便利ですね。

内容の追加

続いてデータ行を増やしてみます。

追加
>>push!(df,("カボチャ",250,100))
4×3 DataFrame
 Row  商品名        値段    在庫  
      String       Int64  Int64 
├─────┼──────────────┼────────┼───────┤
 1    トマト        100     500   
 2    トウモロコシ  150     200   
 3    スイカ        200     300   
 4    カボチャ      250     100   

内容の削除

増やしたデータ行を削除します。

削除
>>deleterows!(df, 4)
3×3 DataFrame
 Row  商品名        値段    在庫  
      String       Int64  Int64 
├─────┼──────────────┼────────┼───────┤
 1    トマト        100     500   
 2    トウモロコシ  150     200   
 3    スイカ        200     300   

内容のソート

在庫を使用してソートをしてみます。

ソート
# 昇順
>>sort!(df,3)
3×3 DataFrame
 Row  商品名        値段    在庫  
      String       Int64  Int64 
├─────┼──────────────┼────────┼───────┤
 1    トウモロコシ  150     200   
 2    スイカ        200     300   
 3    トマト        100     500   

# 降順
>>sort!(df,3,rev=true)
3×3 DataFrame
 Row  商品名        値段    在庫  
      String       Int64  Int64 
├─────┼──────────────┼────────┼───────┤
 1    トマト        100     500   
 2    スイカ        200     300   
 3    トウモロコシ  150     200   

内容の保存

今回変更した内容で保存をしてみます。

>>df |> CSV.write("outputCSV.csv",delim=',',writeheader=true)
"outputCSV.csv"
outputCSV.csv
商品名,値段,在庫
トマト,100,500
スイカ,200,300
トウモロコシ,150,200

在庫が10倍になっているのと、在庫の降順でソートされて保存されいます。

ガイドを読んでみると他にも機能がありそうなので読んでみてください。
今回はこれくらいできれば最低限かなと判断しました。

ここまでのソースコードまとめ

TestCSV.jl
using csv
using DataFrames

# ファイル読み込み
df = CSV.read("sample.csv",header=true,dlim=',')
@show df

# データ内容更新
df[3] = df[3] * 10
# データ更新
push!(df,("カボチャ",250,100))
# データ削除
deleterows!(df, 4)
# データ内容ソート
sort!(df,rev=true)

# データ保存
df |> CSV.write("outputCSV.csv",writeheader=true,dlim=',')

ArrayをDataFrameに変換する

Array形式のデータ(↓)をDataFramesに入れます。

>>l = [1 2 3;4 5 6;7 8 9]
3×3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9
>>df = DataFrames(l)
3×3 DataFrame
 Row  x1     x2     x3    
      Int64  Int64  Int64 
├─────┼───────┼───────┼───────┤
 1    1      2      3     
 2    4      5      6     
 3    7      8      9     

これでとりあえずDataFrame型に変換することが出来ました。
しかしヘッダーがこのままだとよろしくないので、ヘッダーを変更します。

ヘッダー変更

ヘッダー変更
# 一つだけ変更
>>rename!(df,(:x1 => :num1))
3×3 DataFrame
 Row  num1   x2     x3    
      Int64  Int64  Int64 
├─────┼───────┼───────┼───────┤
 1    1      2      3     
 2    4      5      6     
 3    7      8      9     

# 複数を変更
rename!(df,f => t for (f,t) = zip([:x2,:x3],[:num2,:num3]))
3×3 DataFrame
 Row  num1   num2   num3  
      Int64  Int64  Int64 
├─────┼───────┼───────┼───────┤
 1    1      2      3     
 2    4      5      6     
 3    7      8      9     

あとはこれをCSVとして保存すれば完了です。

ここまでのコード

using CSV
using DataFrames

l = [1 2 3;4 5 6;7 8 9]
df = DataFrame(l)
rename!(df,f => t for (f,t) = zip([:x1,:x2,:x3],[:num1,:num2,:num3]))

df |> CSV.write("outputCSV.csv",dlim=',',writeheader=true)

出力結果

outputCSV.csv
num1,num2,num3
1,2,3
4,5,6
7,8,9

次回

今回はCSVの作成方法についての記事を書いたので、次回こそはHTMLからデータを抜き出してCSVに保存する方法をやってみたいと思います。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11