Python CSV を扱う #4

株式会社リュディアです。今回は CSV ファイルの読み込み時の応用編として1行目を読み飛ばす1列目を読み飛ばす方法についてまとめます。

前回までの Python CSV を扱うについてのまとめへのリンクは以下を参考にしてください。

CSV ファイルを見たときにいわゆるデータ部以外に以下のような形式になっていることはないでしょうか。

1行目に各列の項目名が入っている。あるいは生成した日付が入っている。

1列目に各行の項目名が入っている

このような場合には1行目、1列目を読み飛ばす方法はないかな、と考えると思います。今回はそのような場合の対応方法についてです。Numpy を使う方法もあるのですが標準ライブラリのみで対応する方法に特化しています。

今まで使っていたものと同じファイル名ですが以下のような CSV ファイルを準備しました。1行目、1列目に項目名を追加したものです。

画像1

1行目(先頭行)を読み飛ばす方法

前回のまとめに示したプログラム例で上の CSV ファイルを読むと以下のような結果になります。

import csv

l = []

try:
   with open('note_read_sample.csv', 'r', encoding="utf_8-sig") as f:
       reader = csv.reader(f)
       for row in reader:
           l.append(row)
   print(l)
except FileNotFoundError as e:
   print('File not found', e)

# 見やすいように整形済
#
# [['   ', '列1', '列2', '列3', '列4', '列5', '列6', '列7'],
#  ['行1', 'a_1', 'b_1', 'c_1', 'd_1', 'e_1', 'f_1', 'g_1'],
#  ['行2', 'a_2', 'b_2', 'c_2', 'd_2', 'e_2', 'f_2', 'g_2'],
#  ['行3', 'a_3', 'b_3', 'c_3', 'd_3', 'e_3', 'f_3', 'g_3'],
#  ['行4', 'a_4', 'b_4', 'c_4', 'd_4', 'e_4', 'f_4', 'g_4'],
#  ['行5', 'a_5', 'b_5', 'c_5', 'd_5', 'e_5', 'f_5', 'g_5']]

1行目、1列目のデータとして不要な先頭行、先頭列が読み込まれています。まず先頭行を読み飛ばす処理をした以下の例を見てください。

import csv

l = []

try:
   with open('note_read_sample.csv', 'r', encoding="utf_8-sig") as f:
       reader = csv.reader(f)
       next(reader) # 先頭行を読み飛ばす処理
       for row in reader:
           l.append(row)
   print(l)
except FileNotFoundError as e:
   print('File not found', e)

# 見やすいように整形済
#
# [['行1', 'a_1', 'b_1', 'c_1', 'd_1', 'e_1', 'f_1', 'g_1'],
#  ['行2', 'a_2', 'b_2', 'c_2', 'd_2', 'e_2', 'f_2', 'g_2'],
#  ['行3', 'a_3', 'b_3', 'c_3', 'd_3', 'e_3', 'f_3', 'g_3'],
#  ['行4', 'a_4', 'b_4', 'c_4', 'd_4', 'e_4', 'f_4', 'g_4'],
#  ['行5', 'a_5', 'b_5', 'c_5', 'd_5', 'e_5', 'f_5', 'g_5']]

先頭行を読み飛ばすことができましたね。next(reader)が先頭行を読み飛ばすための処理です。reader = csv.reader(f) で CSV ファイルオブジェクト f からファイルを読み込めるようになるのですが、次の next(reader) で reader を次の行に進むよう指示しています。つまり先頭行を飛ばして次の行から読み込むよう指示をしていることになります。

この例では先頭行を完全に捨ててしまいましたが、別データとして先頭行の情報も欲しい場合はどうすればよいでしょうか?以下の例を見てください。

import csv

l = []

try:
   with open('note_read_sample.csv', 'r', encoding="utf_8-sig") as f:
       reader = csv.reader(f)
       head_row = next(reader) # 先頭行を読み飛ばす処理
       print(head_row)
       for row in reader:
           l.append(row)
   print(l)
except FileNotFoundError as e:
   print('File not found', e)

# 見やすいように整形済
#
# ['', '列1', '列2', '列3', '列4', '列5', '列6', '列7']
#
# [['行1', 'a_1', 'b_1', 'c_1', 'd_1', 'e_1', 'f_1', 'g_1'],
#  ['行2', 'a_2', 'b_2', 'c_2', 'd_2', 'e_2', 'f_2', 'g_2'],
#  ['行3', 'a_3', 'b_3', 'c_3', 'd_3', 'e_3', 'f_3', 'g_3'],
#  ['行4', 'a_4', 'b_4', 'c_4', 'd_4', 'e_4', 'f_4', 'g_4'],
#  ['行5', 'a_5', 'b_5', 'c_5', 'd_5', 'e_5', 'f_5', 'g_5']]

実は next(reader) には戻り値があり読み飛ばした行の内容を返します。先頭行を読み飛ばしたいが内容は別途必要という場合は next(reader) の戻り値を利用します。先頭2行を読み飛ばしたいという場合も next(reader) を2回呼べば対応可能です。

1列目(先頭列)を読み飛ばす方法

先頭列を読み飛ばす方法は標準ライブラリのみを使う方法では存在しないと思います。そのためいったん読み込んでから1列目の要素を消去するという方法をとります。上で使った先頭行を読み飛ばす例に1列目を削除する方法を追加した以下の例を見てください。

import csv

l = []

try:
   with open('note_read_sample.csv', 'r', encoding="utf_8-sig") as f:
       reader = csv.reader(f)
       head_row = next(reader) # 先頭行を読み飛ばす処理
       print(head_row)
       for row in reader:
           l.append(row)
       
       for l_row in l:  # 読み込み済みの2次元リストの行に対するループ
           l_row.pop(0) # 各行の先頭列を削除する処理
       
   print(l)
except FileNotFoundError as e:
   print('File not found', e)

# 見やすいように整形済
#
# ['', '列1', '列2', '列3', '列4', '列5', '列6', '列7']
#
# [['a_1', 'b_1', 'c_1', 'd_1', 'e_1', 'f_1', 'g_1'],
#  ['a_2', 'b_2', 'c_2', 'd_2', 'e_2', 'f_2', 'g_2'],
#  ['a_3', 'b_3', 'c_3', 'd_3', 'e_3', 'f_3', 'g_3'],
#  ['a_4', 'b_4', 'c_4', 'd_4', 'e_4', 'f_4', 'g_4'],
#  ['a_5', 'b_5', 'c_5', 'd_5', 'e_5', 'f_5', 'g_5']]

行1, 行2、... となっていた各行の先頭列を読み飛ばせましたね。いったん読み込んだリストの各行の先頭要素を削除するループを追加しました。各行を表すリストに pop(0) の処理を行っています。pop(0) によりリストの 0 番目の要素を削除します。

先頭行のときと同様に削除した先頭列の情報を取得するには以下のようにします。

import csv

l = []

try:
   with open('note_read_sample.csv', 'r', encoding="utf_8-sig") as f:
       reader = csv.reader(f)
       head_row = next(reader) # 先頭行を読み飛ばす処理
       print(head_row)
       for row in reader:
           l.append(row)
       
       head_col = []
       for l_row in l:                   # 読み込み済みの2次元リストの列方向にループ
           head_col.append(l_row.pop(0)) # 先頭列を削除し削除した要素をリストに追加
       
       print(head_col)
       
   print(l)
except FileNotFoundError as e:
   print('File not found', e)

# 見やすいように整形済
#
# ['', '列1', '列2', '列3', '列4', '列5', '列6', '列7']
#
# ['行1', '行2', '行3', '行4', '行5']
#
# [['a_1', 'b_1', 'c_1', 'd_1', 'e_1', 'f_1', 'g_1'],
#  ['a_2', 'b_2', 'c_2', 'd_2', 'e_2', 'f_2', 'g_2'],
#  ['a_3', 'b_3', 'c_3', 'd_3', 'e_3', 'f_3', 'g_3'],
#  ['a_4', 'b_4', 'c_4', 'd_4', 'e_4', 'f_4', 'g_4'],
#  ['a_5', 'b_5', 'c_5', 'd_5', 'e_5', 'f_5', 'g_5']]

next(reader) が読み飛ばした行を戻り値としたのと同様、pop(0) も削除した要素を戻り値とするので pop(0) の戻り値を新規に用意したリスト head_col に追加していくことで削除した列の情報をリストに格納できます。

今回の内容は実際の場で CSV ファイルを読み込むときに直面する問題への対応策です。お役に立てばと思います。

Python CSVを扱うに関するまとめの続きは以下からどうぞ。

では、ごきげんよう。


いいなと思ったら応援しよう!