Pythonで業務の自動化を行うためにはCSVデータの読み込みや操作が不可欠です。
CSVデータはデータ分析でもよく使われ、Pandasを使ってCSVを扱えると非常に便利です。そこでこの記事では、外部ライブラリのpandas
でCSVファイルを読み込む方法を解説します。
使用ライブラリ
インストール:必要
外部ライブラリのpandas
を利用します。
pandas
はデータ解析を支援する機能を提供するライブラリです。表や時系列データを操作するためのデータ構造や演算機能が提供されていて、業務の自動化はもちろん、データ分析や機械学習の前処理にも無くてはならないライブラリです。
ライブラリのインストール
pandas
がインストールされていない場合は、pip
でインストールします。
・関連記事:Pythonライブラリのインストール(pipの使い方)
Successfully installed ・・・・と表示されればインストールは成功です。(依存関係のある他のライブラリも同時にインストールされます)
pandasでCSVファイルを読み込む
サンプルデータ
画像のようにヘッダ(列名)を含むデータ:seiseki.csvと、ヘッダを含まないデータ:seieski_noheader.csv、区切り文字が空白のデータ:seiseki_sep.csvを使用します。
ちなみに上記のCSVファイルをExcelで開くと文字化けします。
これはExcelが初期設定で文字コードをShift-JISで読み込もうとしますが、ファイルはcp932やUTF-8などで保存されていて、文字コードが合わないために発生します。
ライブラリのインポート
まずpandas
をpd
という名前でインポートします。
1 | import pandas as pd |
CSVファイルの読み込み
CSVを読み込むにはread_csv()
メソッドを使用します。
python実行ディレクトリにあるseiseki.csvを読み込んでみます。
1 2 3 | import pandas as pd df = pd.read_csv('seiseki.csv', encoding = 'cp932') df.head() |
pandasのDataFrameとしてシートのデータが読み込まれます。
引数を何も指定しない場合は、インデックスが自動で付与され、1行目がヘッダに設定されます。
インデックスとはデータに対して付与されるラベルで、データの参照や様々な処理で使われます。pandasでデータを扱う際にはインデックスが必要になるため、指定しない場合は自動的に付与されます。
【補足】
日本語が含まれたCSVを読み込む際に、文字コードの指定をencoding='shift-jis'
とすると、以下のようなエラーが表示される場合があります。UnicodeDecodeError: 'shift-jis' codec can't decode byte 0x87 in position 0: invalid start byte
これはShift-JISには無いWindowsの拡張文字が使用されている事が原因です。そのため日本語が含まれるファイルを読み込む際にはencoding='cp932'
としておくのが無難です。
cp932でもエラーが発生する場合は、文字コードにUTF-8 encoding='utf-8'
を指定して読み込みます。
インデックスを指定して読み込む
インデックスを指定して読み込みたい場合は、引数にindex_col
にインデックス番号もしくは列名を指定して読み込みます。
列のインデックス番号は下図のように1列目が0から開始します。今回は1列目をインデックスとして読み込んでみます。
1 2 | df = pd.read_csv('seiseki.csv', encoding='cp932', index_col=0) df.head() |
列名を直接指定しても同じ結果になります。
1 | df = pd.read_csv('seiseki.csv', encoding='cp932', index_col='No') |
複数のインデックスを指定して読み込む
インデックスを複数指定して読み込むこともできます。
1 2 | df = pd.read_csv('seiseki.csv', encoding='cp932', index_col=[0,1]) df.head() |
特定の行を飛ばして読み込む
特定の行だけを飛ばして読み込みたい場合には、引数skiprows
を指定します。飛ばす行番号はリストで指定します。
CSVの4,5行目(No3,4)を飛ばして読み込んでみます。
1 2 | df = pd.read_csv('seiseki.csv', encoding='cp932', index_col=0, skiprows=[3,4]) df.head() |
ヘッダ(列名)を指定しないで読み込む
読み込むファイルにヘッダ(列名)が無い場合、初期設定ではデータ行がヘッダに設定されてしまいます。その場合は引数にheader=None
を指定することでヘッダ無しで読み込む事ができます。
サンプルとして以下のデータ(seieski_noheader.csv)を読み込みます。
1 2 | df = pd.read_csv('seiseki_noheader.csv', encoding='cp932', header=None) df.head() |
ヘッダ(列名)を設定・変更して読み込む
ヘッダ(列名)を設定して読み込みたい場合は、引数names
に列名のリストを指定して読み込みます。
サンプルファイル seieski_noheader.csv を使用します。
1 2 3 4 | df = pd.read_csv('seiseki_noheader.csv', encoding='cp932', names = ['No','Name','Jpn','Mth','Sci','Sct','Eng','Total']) df.head() |
元のデータにヘッダが含まれている場合は、skip_rows=0
で1行目を飛ばして2行目から読み込み、列名を設定することで変更します。(seiseki.csv を使用)
1 2 3 4 5 | df = pd.read_csv('seiseki.csv', encoding='cp932', skiprows=[0], names = ['No','Name','Jpn','Mth','Sci','Sct','Eng','Total']) df.head() |
欠損値を指定して読み込む
空白の値を読み込むと欠損値を示すNaNとして読み込まれますが、「-」などの文字を欠損値として扱うには、引数 na_values
を指定して読み込みます。
サンプルデータの30, 31行目には、空白と「-」のデータが含まれています。標準では空白のみ欠損値NaNとして扱われるため、na_values
に「-」を指定して欠損値として読み込みます。
1 2 | df = pd.read_csv('seiseki.csv', encoding='cp932', na_values=['-']) df |
どちらも欠損値NaNとして読み込まれました。
区切り文字を指定して読み込む
区切り文字が「,」ではなく空白などの場合は、引数sep
もしくはdelimiter
を指定して読み込みます。
pandasオブジェクト.read_csv(ファイルパス, delimiter=区切り文字)
サンプルファイル seiseki_sep.csv を使用します。
1 2 | df = pd.read_csv('seiseki_sep.csv', encoding='cp932', sep=' ') df.head() |
ファイルの一部だけを読み込む
ファイルの一部のデータを読み込みたい時は nrows
で行数を指定します。
大きなファイルを扱う時に、どのような引数を使えば正しく処理できるかを把握したい時に使用、処理時間を短縮することができます。
1 2 | df = pd.read_csv('seiseki.csv',encoding='cp932', nrows=5) df |
ファイルを少しずつ読み込む
大きいファイルを一気に読み込むと時間がかかる時など、ブロックに分けて少しずつ読み込むには chunksize
で読み込む行数を指定します。
1 2 3 | reader = pd.read_csv('seiseki.csv',encoding='cp932', chunksize=10) reader # <pandas.io.parsers.readers.TextFileReader at 0x2223bb33280> |
chunksize
を指定すると、返り値は DataFrame ではなく TextFileReader インスタンスとなります。
インスタンスの中身は、以下のように for
文でブロックごとの DataFrame として取り出すことができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | i = 1 for chunk in chunker: print('ブロック', i) print(piece.shape) i += 1 # ブロック 1 # (10, 8) # ブロック 2 # (10, 8) # ブロック 3 # (10, 8) # ブロック 4 # (10, 8) # ブロック 5 # (5, 8) |
DataFrame として呼び出したい場合は、get_chunk()
メソッドを使用します。引数に呼び出す行数を指定できます。
1 2 | chunker = pd.read_csv('seiseki.csv', encoding='cp932', chunksize=10) chunker.get_chunk(3) |
1 | chunker.get_chunk(3) |
TextFileReader は読み込まれた位置(ポインタ)を記憶しており、全て読み込むと終了します。
例として、合計が400以上の行を抽出してみます。
1 2 3 4 5 6 | df_total = pd.DataFrame() chunker = pd.read_csv('seiseki.csv', encoding='cp932', chunksize=10) for chunk in chunker: df = chunk[chunk['合計'] > 400] df_total= pd.concat([df_total,df]) df_total |
pandasでCSVファイルを読み込む方法を解説しました。
・関連記事:PythonでCSVファイルを読み込み・書き込み
・関連記事:pandasでExcelファイルの読み込み(read_excel)
・関連記事:pandasでExcelファイルの書き込み(to_excel)
・関連記事:PythonでExcelファイルを操作する(openpyxl)