pythonでのcsvファイル読み込み
python初心者の私、csvファイル、テキストファイルの読み込みの方法がいろいろあって、ごちゃごちゃしてきたのでまとめてみました。
基本的に私が扱うことが多い下図のような1行目ヘッダー、2行目以降数字列のデータを主な対象として考え、どれも最終的にnumpy行列にすることを考えました。
調べて出てきた方法は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の読み込みも使っていきたいなぁと思いました。