Pythonでデータファイルを1行ずつ読み込む方法 | Dr.コード

Pythonでデータファイルを1行ずつ読み込む方法

Pythonでデータファイルを1行ずつ読み込む方法

データの解析時に.csvや.datのファイルを1行ずつ読み込みたいってことありますよね。この記事では、Pythonを使ってファイルを1行ずつ読み込む方法を具体的に解説していきます。

動作環境
macOS Catalina(10.15.3), python3.7.6, Atomエディタ1.44.0

ファイルを読み込むまでの流れ

ファイルを読み込む手順は次のようになります。
1. ファイルを用意する
2. 読む込むためのコードをかく
3. プログラムを実行する

datファイルやcsvファイルなどのファイルの種類が変わっても基本的にやることは同じですが、書くコードが少しだけ異なります。
まずはdatファイルのデータを読み込む方法を見ていきましょう。

datファイルを1行ずつ読み込む方法

datファイルを準備しよう

AvrgTmp_Kyoto2018.dat という2018年の京都市における各月の平均気温のデータが格納されたデータファイルを用意しました。

AvrgTmp_Kyoto2018.dat

# averaged temperature in 2018 @ Kyoto city
# 01: month  02: averaged temperature in the daytime
1 3.9
2 4.4
3 10.9
4 16.4
5 20.0
6 23.4
7 29.8
8 29.5
9 23.6
10 18.7
11 13.5
12 8.2

一列目には月、二列目に日中の平均気温が並んでいます。
一列目と二列目は (半角スペース)で区切られています。
また、# で始まる行はコメント部分を意味します。
.dat という拡張子はデータが格納されたファイルを意味しており、ただのテキストファイルと同じだと思ってください。

Desktop/Dr.code/python/data-analysis/Input_File_Eachrow というディレクトリにこのAvrgTmp_Kyoto2018.dat を保存しておきます。

読み込むためのコードを書こう

AvrgTmp_Kyoto2018.datと同じ階層にInputFile.py と名付けたファイルを保存します。
いきなり結論から入りますが、ファイルを読み込むためのコードは次のように書きます。

InputFile.py

data = open('AvrgTmp_Kyoto2018.dat', 'r')

for line in data:
    if line[0]=='#':
        continue
    lines = line.rstrip('\n').split(' ')
    month = lines[0]
    aveTmp = lines[1]
    print(month, aveTmp)

data.close()

プログラムを実行しよう

上記のプログラムを実行してみましょう。
ターミナルを開いて、cwdをDesktop/Dr.code/python/data-analysis/Input_File_Eachrow にして、実行します。
(→やり方がわからない方はプログラムを実行する方法を参考にしてください。)

ターミナル

$ python InputFile.py
# (実行結果)
# 1 3.9
# 2 4.4
# 3 10.9
# 4 16.4
# 5 20.0
# 6 23.4
# 7 29.8
# 8 29.5
# 9 23.6
# 10 18.7
# 11 13.5
# 12 8.2

うまくいけば上のように実行結果が表示されると思います。
なんの説明もなかったので、次はそれぞれの行が何を意味するかを説明します。

コードの解説

data = open('AvrgTmp_Kyoto2018.dat', 'r')

open(filename)でファイルを開きます。
data = open(filename)としているので、そのファイルに格納されているデータをdataという引数に入れています。r は読み込みmodeを意味します。open()はデフォルトで読み込みmodeなので、今回の場合は rの部分を省略して、open('AvrgTmp_Kyoto2018.dat')と書いても問題ありません。
for line in data:

for xxx in ooo:というforループの構文です。
xxxの部分にlineと記述していますが、好きな文字でいいです。わかりやすく行という意味でrowとかでも。
この構文の処理内容ですが、
1. ooo のデータを1行取り出して、xxxに格納
2. for 以下に記述してる処理を実行する
1 → 2の処理を繰り返し、oooに格納されているデータの最後の行まで処理を行ったら終了
if line[0]=='#':

lineには各行の情報が格納されています。
line[0]lineというリストの一番最初のデータを意味します。
例えば、lineの中にこんにちはという文字列が格納されていたなら、
line[0]line[1]line[2] 、、、ということです。
なので、この行の意味はもしline[0]が#なら~を実行するとなります。
lines = line.rstrip('\n').split(' ')

line.rstrip('\n')'\n'(改行)をlineの末尾から削除するという処理です。
print(line)を実行してみるとわかるのですが、
例えば1 3.9\nとなっています。3.9のすぐ後に改行が入っています。この改行を削除しています。
次に.split(' ')ですが、' '(スペース) で文字列を分割するという処理です。分割された文字列は今回ならlinesという引数に格納されます。
こんな感じで ['1', '3.9']
これらはlines[0] lines[1]で取り出せます。
data.close()

openしたらならcloseしましょう。お作法です。

(参考) コメント部分の除外方法

上ではコメント部分を除外するためにif line[0]=='#': continueと記述しましたが、python標準搭載のre.matchモジュールを使えば少しだけシンプルに記述できます(pythonにこなれてる感が出せるぞ)。
モジュールを使った場合のコード全体は次のようになります。

inputFile.py

import re

data = open('AvrgTmp_Kyoto2018.dat', 'r')

for line in data:
    if not re.match('#', line):
        lines = line.rstrip('\n').split(' ')
        month = lines[0]
        aveTmp = lines[1]
        print(month, aveTmp)

data.close()
MEMO
re.matchモジュールを使う場合は上部でimport reと記述しましょう
if not re.match('#', line):

もしlineの先頭が#でないなら、以下の処理を実行する。という処理になります。これにより、#が先頭についた行を除外できます。

csvファイルを1行ずつ読み込む方法

csvファイルが何かを知っていれば、上記のコードを少し変更するだけで読み込めます。csvファイルとは Comma-Separated Valuesファイルの略で、コンマ区切りされたファイルのことです。よって、スペース区切りだったところをコンマ区切りに変更すれば良いのです。

csvファイルを準備しよう

AvrgTmp_Kyoto2018.csv というファイルを用意しました。
上と同じく、Desktop/Dr.code/python/data-analysis/Input_File_Eachrow に置きます。
中身は以下のようになっています。

AvrgTmp_Kyoto2018.csv

# averaged temperature in 2018 @ Kyoto city
# 01: month  02: averaged temperature in the daytime
1,3.9
2,4.4
3,10.9
4,16.4
5,20.0
6,23.4
7,29.8
8,29.5
9,23.6
10,18.7
11,13.5
12,8.2

なお、Atomエディターでcsvを開く場合はtablrというプラグインをインストールしましょう。
pluginのinstall画面でtablrで検索すれば、インストールはすぐにできます。

読み込むためのコードを書こう

line.rstrip('\n').split(' ')line.rstrip('\n').split(',')に書き換えればOKです!
全体のコードは次のようになります。
出力結果もdatファイルの時と同じになります。

InputFile.py

import re

data = open('AvrgTmp_Kyoto2018.csv', 'r')

for line in data:
    if not re.match('#', line):
        lines = line.rstrip('\n').split(',')
        month = lines[0]
        aveTmp = lines[1]
        print(month, aveTmp)

data.close()

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です