1.Pythonによるファイル読込・出力

本サイトでは、csvファイルsample1.csvを読み込む場合を例として説明します。


図1-1 sample1.csv
図1-1 sample1.csv

1.1.ファイルOpen / Close


ファイルを読み書きするには必ずファイルを開く必要があり、以下のコマンドによって行います。


ファイルオブジェクト名 = open(ファイルパス,モード)

ex) fopen=open('sample1.csv', 'rt')

“ファイルパス”は読み書きしたいファイルの“保存先ディレクトリ\ファイル名”を指定します。 ディレクトリは絶対パス、相対パスのどちらでも構いません。

“モード”は、ファイルの操作方法やファイルのタイプを指定するためのもので、次のようなものがあります。


r: 読み取り操作。
w: 書き出し操作。ファイルが存在しない場合新しいファイルが作成され、存在する場合は、内容が上書きされます。
x: 書き出し操作。ファイルが存在しない場合に指定します。
a: 書き出し操作。ファイルが存在し、その末尾に追記する場合に指定します。
t: テキストファイルであることを指定します。
b: バイナリファイルであることを指定します。

ex)の'rt'は、“読み取り操作”(=r)で“テキストファイル”(=t)であることを意味します。


また、ファイルを開いたら最後にファイルを閉じる操作が必要で、コマンドは以下の通りです。


ファイルオブジェクト名.close()

ex) fopen.close

1.2.ファイルの読込

1.2.1.ファイル全体を一度に読み込む


次のサンプルコードによって、サンプルファイルsample1.csvの中身を一度に読み出し、変数“readData”に引き当てることができます。

read_file1_2_1.py

#File Open
getFN='sample1.csv'
fopen=open(getFN,"rt")

#File Read
readData=fopen.read()

#File Close
fopen.close

#確認用
print (readData)

実行結果は以下のようになります。


X1,X2,X3,X4,X5,X6,X7,X8
3.00E-03,-3.70E-02,1.30E+00,-1.70E+01,1.54E-04,2.82E+02,1.90E-03,3.00E+02
3.00E-03,-3.60E-02,1.00E-01,-1.70E+01,1.42E-04,2.81E+02,2.40E-03,3.00E+02
3.00E-03,-3.60E-02,1.20E-01,-1.70E+01,1.48E-04,2.81E+02,1.70E-02,3.00E+02
3.00E-03,-3.50E-02,-9.50E-01,-1.60E+01,1.20E-04,2.77E+02,1.20E-02,3.00E+02
3.00E-03,-3.40E-02,-1.10E-01,-1.50E+01,1.05E-04,2.75E+02,5.60E-03,3.00E+02
・・・

この方法は、読み込むファイルの容量分メモリも消費しますので、容量の大きいファイルでは要注意です。


1.2.2.ファイルを一行ずつ読み込む


(1)テキスト形式で読み込み

fopenの中のデータを一行ずつ変数lineとして取り出して、変数readDataに追加していきます。

read_file1_2_2_1.py

sample1.csv

#File Open
getFN='sample1.csv'
fopen=open(getFN,"rt")

#File Read
readData=''	#変数準備
for line in fopen:
	readData+=line

#File Close
fopen.close

#確認用
print (readData)

実行結果は以下のようになります。


X1,X2,X3,X4,X5,X6,X7,X8
3.00E-03,-3.70E-02,1.30E+00,-1.70E+01,1.54E-04,2.82E+02,1.90E-03,3.00E+02
3.00E-03,-3.60E-02,1.00E-01,-1.70E+01,1.42E-04,2.81E+02,2.40E-03,3.00E+02
3.00E-03,-3.60E-02,1.20E-01,-1.70E+01,1.48E-04,2.81E+02,1.70E-02,3.00E+02
3.00E-03,-3.50E-02,-9.50E-01,-1.60E+01,1.20E-04,2.77E+02,1.20E-02,3.00E+02
3.00E-03,-3.40E-02,-1.10E-01,-1.50E+01,1.05E-04,2.75E+02,5.60E-03,3.00E+02
・・・

(2)リスト形式で読み込み

上記“readData”をlistで定義すると、

read_file1_2_2_2.py

sample1.csv

#File Read
readData=[]
for line in fopen:
	readData.append(line)

実行結果は以下のようになります。


['X1,X2,X3,X4,X5,X6,X7,X8\n', 
'3.00E-03,-3.70E-02,1.30E+00,-1.70E+01,1.54E-04,2.82E+02,1.90E-03,3.00E+02\n', 
'3.00E-03,-3.60E-02,1.00E-01,-1.70E+01,1.42E-04,2.81E+02,2.40E-03,3.00E+02\n', 
・・・

(3)リスト形式で読み込み(その2)

“.readlines()”は、一行ずつデータをまとめてリスト形式で戻す方法です。

read_file1_2_2_3.py

sample1.csv

#File Open
getFN='sample1.csv'
fopen=open(getFN,"rt")

#File Read
readData=fopen.readlines()

#File Close
fopen.close

print (readData)


実行結果は(2)と同じになります。


['X1,X2,X3,X4,X5,X6,X7,X8\n', 
'3.00E-03,-3.70E-02,1.30E+00,-1.70E+01,1.54E-04,2.82E+02,1.90E-03,3.00E+02\n', 
'3.00E-03,-3.60E-02,1.00E-01,-1.70E+01,1.42E-04,2.81E+02,2.40E-03,3.00E+02\n', 
・・・


1.2.3.ファイルの自動クローズ


1.2.11.2.2節で示したソースは必ず“.close”によってファイルクローズの指定をしていました。

しかし以下のソースによって指定すれば、with文内の処理が完了すると、自動的にファイルクローズが実行されます。

下記サンプルは1.2.2節(1)を書き換えたものです。

read_file1_2_3_1.py

sample1.csv

getFN='sample1.csv'

readData=''
with open(getFN,"rt") as fopen:
	for line in fopen:
		readData+=line

print (readData)

実行結果は1.2.2節(1)と同じです。


1.3.ファイルの書き込み


面白くない例ですが、sample1.csvの中身を取得して、それを“copy.csv”に出力します。 さらに、追記モードで同じデータを“copy.csv”の後ろに追記します。

read_file1_3_1.py

sample1.csv

#データ取得
getFN='sample1.csv'
fopen=open(getFN,"rt")
readData=fopen.read()
fopen.close

#copy.csvに出力
fout=open('copy.csv','wt')
fout.write(readData)
fout.close

#copy.csvに追加出力
fout=open('copy.csv','at')
fout.write(readData)
fout.close

書き込みは“print”を使っても可能です。


#copy.csvに出力
fout=open('copy.csv','wt')
print (readData,file='copy.csv')
fout.close

#または
with open('copy.csv','wt') as fout:
	print (readData,file='copy.csv')

書き込みに対する他の引数として次のものがあります。


sep セパレータ。デフォルトではスペース(' 'または\s)が設定されます。
end 末尾の文字列。デフォルトでは改行('\n')が設定されます。

1.4.csvファイルの読み書き


Pythonにはcsvファイルフォーマットに対応したコマンドが準備されています。 それを使うには“import csv”の宣言が必要になります。

(1)csvの読み込み

read_file1_4_1.py

sample1.csv

import csv

getFN='sample1.csv'
with open(getFN,"rt") as fopen:
	csvData=csv.reader(fopen)
	
	readData=[]
	for line in csvData:
		readData.append(line)

print (readData)

実行結果は以下のようになります。


[['X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8'], 
['3.00E-03', '-3.70E-02', '1.30E+00', '-1.70E+01', '1.54E-04', '2.82E+02', '1.90E-03', '3.00E+02'], 
['3.00E-03', '-3.60E-02', '1.00E-01', '-1.70E+01', '1.42E-04', '2.81E+02', '2.40E-03', '3.00E+02'], 
・・・

また“csv.DictReader”を使うことで列名を指定でき、連想配列的な使い方ができます。

read_file1_4_2.py

sample1.csv

import csv

fdName=['X1','X2','X3','X4','X5','X6','X7','X8']
getFN='sample1.csv'
with open(getFN,"rt") as fopen:
	csvData=csv.DictReader(fopen,fieldnames=fdName)
	
	cnt1=0
	readData=[]
	for line in csvData:
		
		#二行目以降データ取得
		if cnt1>0:
			readData.append(line)
		else:
			cnt1+=1

print (readData)


実行結果は以下のようになります。


[{'X6': '2.82E+02', 'X7': '1.90E-03', 'X5': '1.54E-04', 'X2': '-3.70E-02', 'X4': '-1.70E+01', 'X3': '1.30E+00', 'X1': '3.00E-03', 'X8': '3.00E+02'}, 
{'X6': '2.81E+02', 'X7': '2.40E-03', 'X5': '1.42E-04', 'X2': '-3.60E-02', 'X4': '-1.70E+01', 'X3': '1.00E-01', 'X1': '3.00E-03', 'X8': '3.00E+02'}, 
{'X6': '2.81E+02', 'X7': '1.70E-02', 'X5': '1.48E-04', 'X2': '-3.60E-02', 'X4': '-1.70E+01', 'X3': '1.20E-01', 'X1': '3.00E-03', 'X8': '3.00E+02'}, 
・・・

列の順番がバラバラな理由はわかりません...。


(2)csvの書き込み

例として、sample1.csvからX2、X4、X6列を抽出して、それを“resdata.csv”に出力します。

read_file1_4_3.py

sample1.csv


import csv

getFN='sample1.csv'
with open(getFN,"rt") as fopen:
	csvData=csv.reader(fopen)
	
	readData=[]
	for line in csvData:
		readData.append(line)

#X2,X4,X6のみ残す
delNo=[7,6,4,2,0]
tmp=[]
for line in readData:
	for cnt1 in delNo:
		del line[cnt1]
	tmp.append(line)

readData=tmp

#ファイル出力
with open('resdata.csv','wt') as fout:
	csvout=csv.writer(fout, lineterminator='\n')
	csvout.writerows(readData)

resdata.csv出力結果は以下のようになります。


図1-4-1 resdata.csv出力結果
図1-4-1 resdata.csv出力結果


参考文献