ふぎのモノづくりにっき

痛車乗りのモノづくり日記。いろいろ試したり、作ったりするのを載せる予定だぞいッ

pythonでのcsvファイル読み込み

 python初心者の私、csvファイル、テキストファイルの読み込みの方法がいろいろあって、ごちゃごちゃしてきたのでまとめてみました。

 基本的に私が扱うことが多い下図のような1行目ヘッダー、2行目以降数字列のデータを主な対象として考え、どれも最終的にnumpy行列にすることを考えました。
f:id:nyanpasuAxela:20190218200715p:plain


 調べて出てきた方法は5つ
                           
csvモジュールを使用する方法 ⇒ 1回で1行読み込み。出力はカンマで区切ったlist型、list内はstr型['0', ' 0.0074', ' 0.0083', ' 0.0826', ' 0.0823']
②for line in file:で読み込む方法 ⇒ 1回で1行読み込み。出力はstr型"0, 0.0074, 0.0083, 0.0826, 0.0823\n"
③.readlines()を使用する方法 ⇒ 1回で全文読み込み。出力はlist型,list内は1行1要素のstr型['0, 0.0074, 0.0083, 0.0826, 0.0823\n', '1, 0.0118,...']
④numpy関数np.loadtxtを使用する方法 ⇒ 1回で全文読み込み。出力はnumpy行列
⑤pandasを使用する方法 ⇒ 1回で全文読み込み。出力はpd.DataFrame型


csvモジュールを使用する方法

import csv
import numpy as np
listcsv=[]
with open(file_path, "r") as f1:
    csvreader=csv.reader(f1)#反復できるreaderオブジェクト 
    next(csvreader)#1行目のヘッダーを飛ばす

    for line in csvreader:  #line:カンマで区切ったlist型, list内はstr型['0', ' 0.0074', ' 0.0083', ' 0.0826', ' 0.0823']
        line = [float(i.strip()) for i in line]  #空白を削除、数値型へ変換['0', '0.0074', '0.0083', '0.0826', '0.0823']
        listcsv.append(line)

npcsv=np.array(listcsv)  #numpy型化。shape(600,5)

csv.reader(filename)で反復オブジェクトを生成し、for文で1行ずつ読み込んでいます。読み込んだデータはデフォルトでは”,”で区切られた文字列になっています。

数字列で扱いたい場合はfloat型に変換して、その後appendで各行積み上げていっています。今回のcsvファイルは、','以外に空白が入っていたため、空白、タブ、段落を除去するstrip()を使用しています。
最後にlistをnumpy配列化しています。


②for line in file:で読み込む方法

listcsv=[]
with open(file_path, "r") as f1:
    next(f1)
    
    for line in f1:  #line:str型 "0, 0.0074, 0.0083, 0.0826, 0.0823\n"
        line=line.split(',')   #","で分割してリスト化。リスト内はstr型['0', ' 0.0074', ' 0.0083', ' 0.0826', ' 0.0823\n']
        line = [float(i.strip()) for i in line]  #空白・改行削除、数値型へ変換(※この1行を消してもnumpy型化できた)[0.0, 0.0074, 0.0083, 0.0826, 0.0823]
        listcsv.append(line)

npcsv=np.array(listcsv)  #numpy型化。shape(600,5)

 開いたファイルをそのままfor文で1行づつ読み込む方法。読み込まれるデータは文字列なので.split(',')で自分で指定した文字でリストに分割します。後は、「①csvモジュールを使用した場合」と同様に空白・段落除去してfloat化してnumpy配列化しています。

1行づつ文字列で読み込むので、csv以外でも、その後にif文で処理を入れれば自由度がとても高そうです。


③.readlines()を使用する方法

with open(file_path, "r") as f1:
    next(f1)
    listcsv=f1.readlines()#listcsv:list型,list内はstr型print(listcsv)['0, 0.0074, 0.0083, 0.0826, 0.0823\n', '1, 0.0118,...']
    for index in range(len(listcsv)):
        listcsv[index] = listcsv[index].split(',')  #リスト内それぞれ','で区切る。
        listcsv[index] = [float(i.strip()) for i in listcsv[index]]  #空白・改行削除、数値型へ変換

npcsv=np.array(listcsv)  #numpy型化。shape(600,5)

 readlinesを使えば、全文を1行1要素とした文字列リストとしてファイルを読むことができます。上の例ではリストとして読み込んだ後に、各要素を方法②と同じく区切って、空白・改行除去・数値型へ変換しnumpy配列にしています。

 readlinesに似た関数があるので下に2つ示します。
#readーーーファイル内全てを改行コード含めた1つの文字列にする⇒出力:str(すごく長い)
#readlineーーーファイル内の1行を文字列として読み込む⇒出力:str(1行分)
#readlinesーーーファイル内全てリストとして読み込み、1行1要素の文字列⇒出力:list[str, str, str, ...]


④numpy関数np.loadtxtを使用する方法

npcsv = np.loadtxt(file_path, skiprows=1, delimiter=',', usecols=(1,3), dtype='float')   #skiprowsは飛ばしたい行数、delimiterは区切る文字、usecolsは読み込みたい列(未指定時は全列使用)

 numpy配列としてファイル全文を直接読み込むことができます。飛ばしたい行数や、区切り文字、読み込みたい列の指定などもできます。


⑤pandasを使用する方法

pdcsv = pd.read_csv(file_path,header=0)
#オプションの一部
#delimiter:区切り文字指定可能
#header:ヘッダー行指定
#index_col:行のインデックスに使う列指定

npcsv=pdcsv.values

 pandas.DataFrameとしてファイル全文を直接読み込むことができます。
 オプションでヘッダー行指定、区切り文字設定などもできます。





 それぞれ特徴があるので、場合によって何が良いかはわかりませんが、私的には覚えることが少なくて汎用性の高そうな”②for line in file:で読み込む方法”が好みで、使用目的が決まってるなら④、⑤のnumpy, pandasの読み込みも使っていきたいなぁと思いました。