pandasでCSV/TSVファイル読み込み(read_csv, read_table)

Modified: | Tags: Python, pandas, CSV

pandasでCSVファイルやTSVファイルをDataFrameとして読み込むにはread_csv()を使う。

CSVファイルへの書き込み・追記については以下の記事を参照。

pandasでのExcel, JSON, pickleファイルの読み書き(入出力)については以下の記事を参照。

日時情報を含むCSVファイルを時系列データとして読み込む方法については以下の記事を参照。

本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。

import pandas as pd

print(pd.__version__)
# 2.0.3

read_csv()の基本的な使い方

read_csv()の第一引数にCSVファイルのパスを指定するとDataFrameとして読み込まれる。

df = pd.read_csv('data/src/sample_header.csv')
print(df)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

パスは絶対パスでも相対パスでもよい。カレントディレクトリの確認や変更については以下の記事を参照。

デフォルトでは、CSVファイルの一行目(ヘッダー)が列名columnsとして扱われる。read_csv()の引数によって、ヘッダーの扱いなどの様々な項目を設定できる。

以下、多くのユースケースで必要となると思われる主要な引数について説明する。本記事で扱っていない引数も数多くあるので、詳細は公式ドキュメントを参照されたい。

headerがないCSVの読み込み: 引数header, names

header(見出し行)がない以下のようなCSVファイルを読み込む。

11,12,13,14
21,22,23,24
31,32,33,34
source: sample.csv

デフォルトでは一行目がheaderとして認識され、列名columnsに割り当てられる。

df = pd.read_csv('data/src/sample.csv')
print(df)
#    11  12  13  14
# 0  21  22  23  24
# 1  31  32  33  34

print(df.columns)
# Index(['11', '12', '13', '14'], dtype='object')

引数headerNoneとすると0始まりの連番が列名columnsになる。

df_none = pd.read_csv('data/src/sample.csv', header=None)
print(df_none)
#     0   1   2   3
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

任意の値を列名として設定するには、引数namesにリストやタプルで指定する。

df_names = pd.read_csv('data/src/sample.csv', names=['A', 'B', 'C', 'D'])
print(df_names)
#     A   B   C   D
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

headerがあるCSVの読み込み: 引数header, names

headerがある以下のようなCSVファイルを読み込む。

a,b,c,d
11,12,13,14
21,22,23,24
31,32,33,34

上述のように、デフォルトで一行目がheaderとして認識され、列名columnsに割り当てられる。

df = pd.read_csv('data/src/sample_header.csv')
print(df)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

一行目とは別の任意の値を列名として設定するには、header=0とした上で、引数namesにリストなどで指定する。header=0がないと一行目がデータとして残ってしまうので注意。

df_names = pd.read_csv('data/src/sample_header.csv', names=['A', 'B', 'C', 'D'])
print(df_names)
#     A   B   C   D
# 0   a   b   c   d
# 1  11  12  13  14
# 2  21  22  23  24
# 3  31  32  33  34

df_names_0 = pd.read_csv('data/src/sample_header.csv',
                         header=0, names=['A', 'B', 'C', 'D'])
print(df_names_0)
#     A   B   C   D
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

header=2のようにheaderとして扱う行番号を0始まりで指定することもできる。指定した行より上の行は無視される。

df_header_2 = pd.read_csv('data/src/sample_header.csv', header=2)
print(df_header_2)
#    21  22  23  24
# 0  31  32  33  34

indexがあるCSVの読み込み: 引数index_col

headerとindex(見出し列)がある以下のようなCSVファイルを読み込む。

,a,b,c,d
ONE,11,12,13,14
TWO,21,22,23,24
THREE,31,32,33,34

デフォルトでは行名indexは0始まりの連番となる。一列目は特別扱いされない。

df = pd.read_csv('data/src/sample_header_index.csv')
print(df)
#   Unnamed: 0   a   b   c   d
# 0        ONE  11  12  13  14
# 1        TWO  21  22  23  24
# 2      THREE  31  32  33  34

print(df.index)
# RangeIndex(start=0, stop=3, step=1)

引数index_colindexとして使いたい列の列番号を0始まりで指定できる。

df_index_col = pd.read_csv('data/src/sample_header_index.csv', index_col=0)
print(df_index_col)
#         a   b   c   d
# ONE    11  12  13  14
# TWO    21  22  23  24
# THREE  31  32  33  34

print(df_index_col.index)
# Index(['ONE', 'TWO', 'THREE'], dtype='object')

列を指定(選択)して読み込み: 引数usecols

特定の列だけを読み込むには、引数usecolsを使う。読み込む列番号または列名をリストで指定する。

df_usecols = pd.read_csv('data/src/sample_header.csv', usecols=[1, 3])
print(df_usecols)
#     b   d
# 0  12  14
# 1  22  24
# 2  32  34

df_usecols = pd.read_csv('data/src/sample_header.csv', usecols=['a', 'c'])
print(df_usecols)
#     a   c
# 0  11  13
# 1  21  23
# 2  31  33

ラムダ式などの呼び出し可能オブジェクトも指定可能。列名が渡され、真となる列のみが抽出される。特に列数が多いファイルから少数の列を除外して読み込みたいときは、読み込む列名や列番号を大量に指定するより楽。

df_usecols = pd.read_csv('data/src/sample_header.csv',
                         usecols=lambda x: x != 'b')
print(df_usecols)
#     a   c   d
# 0  11  13  14
# 1  21  23  24
# 2  31  33  34

df_usecols = pd.read_csv('data/src/sample_header.csv',
                         usecols=lambda x: x not in ['a', 'c'])
print(df_usecols)
#     b   d
# 0  12  14
# 1  22  24
# 2  32  34

行をスキップ(除外)して読み込み

先頭のn行または行番号を指定してスキップ: 引数skiprows

特定の行をスキップ(除外)して読み込むには、引数skiprowsを使う。

整数を指定すると、ファイルの先頭n行をスキップして読み込む。

df = pd.read_csv('data/src/sample.csv', header=None)
print(df)
#     0   1   2   3
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

df_skiprows = pd.read_csv('data/src/sample.csv', header=None, skiprows=2)
print(df_skiprows)
#     0   1   2   3
# 0  31  32  33  34

スキップする行番号をリストで指定することもできる。usecolsとは違って、指定するのは読み込む行ではなくスキップする行。

df_skiprows = pd.read_csv('data/src/sample.csv', header=None, skiprows=[0, 2])
print(df_skiprows)
#     0   1   2   3
# 0  21  22  23  24

ラムダ式などの呼び出し可能オブジェクトも指定可能。行番号が渡され、真となる行をスキップする。特に行数が多いファイルから特定の行だけを読み込みたいときは、スキップする行番号を大量に指定するより楽。

df_skiprows = pd.read_csv('data/src/sample.csv', header=None,
                          skiprows=lambda x: x not in [0, 2])
print(df_skiprows)
#     0   1   2   3
# 0  11  12  13  14
# 1  31  32  33  34

headerがあるファイルの場合、headerの行が0行目として扱われるので注意。

df_skiprows = pd.read_csv('data/src/sample_header.csv', skiprows=2)
print(df_skiprows)
#    21  22  23  24
# 0  31  32  33  34

df_skiprows = pd.read_csv('data/src/sample_header.csv', skiprows=[1, 3])
print(df_skiprows)
#     a   b   c   d
# 0  21  22  23  24

なお、index_colindexとして扱う列を指定していてもskiprowsを行名で指定することはできない。

末尾のn行をスキップ: 引数skipfooter

ファイルの末尾をスキップするには、引数skipfooterを使う。スキップする末尾の行数を整数で指定する。

df_skipfooter = pd.read_csv('data/src/sample.csv', header=None,
                            skipfooter=1, engine='python')
print(df_skipfooter)
#     0   1   2   3
# 0  11  12  13  14
# 1  21  22  23  24

環境によっては以下のようなWarningが出るので、引数engine='python'を指定する。

ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support skipfooter; you can avoid this warning by specifying engine='python'.

先頭のn行のみ読み込み: 引数nrows

引数nrowsを使うと、最初n行だけを読み込むことができる。大きいサイズのファイルのデータを少し確認する場合に便利。

df_nrows = pd.read_csv('data/src/sample.csv', header=None, nrows=2)
print(df_nrows)
#     0   1   2   3
# 0  11  12  13  14
# 1  21  22  23  24

headerがあるファイルの場合、headerの行はカウントに含まれない。

df_nrows = pd.read_csv('data/src/sample_header.csv', nrows=2)
print(df_nrows)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24

データ型(dtype)を指定して読み込み

pandas.DataFrameは列ごとにデータ型dtypeが設定されている。文字列とobject型との関係など詳細は以下の記事を参照。

read_csv()では各列のデータ型が値から推測されて自動的に選ばれるが、引数dtypeで明示的に指定することもできる。

以下のファイルを例とする。

,a,b,c,d
ONE,1,"001",100,x
TWO,2,"020",,y
THREE,3,"300",300,z

例えば、0で始まる数値の列は引用符で囲まれていてもいなくてもデフォルトでは数値とみなされ、先頭の0は無視される。

df = pd.read_csv('data/src/sample_header_index_dtype.csv', index_col=0)
print(df)
#        a    b      c  d
# ONE    1    1  100.0  x
# TWO    2   20    NaN  y
# THREE  3  300  300.0  z

print(df.dtypes)
# a      int64
# b      int64
# c    float64
# d     object
# dtype: object

先頭の0を含む文字列として扱いたい場合は、read_csv()の引数dtypeを指定する。

すべての列に同じデータ型dtypeを指定

引数dtypeに任意のデータ型を指定すると、index_colで指定した列も含めてすべての列がその型に変換される。

指定した型に変換できない値があるとエラーになるので注意。

# pd.read_csv('data/src/sample_header_index_dtype.csv',
#             index_col=0, dtype=float)
# ValueError: could not convert string to float: 'ONE'

dtype=strとすると、すべての列が文字列に変換される。ただし、この場合も欠損値NaNfloat型。

df_str = pd.read_csv('data/src/sample_header_index_dtype.csv',
                     index_col=0, dtype=str)
print(df_str)
#        a    b    c  d
# ONE    1  001  100  x
# TWO    2  020  NaN  y
# THREE  3  300  300  z

print(df_str.dtypes)
# a    object
# b    object
# c    object
# d    object
# dtype: object

print(df_str.applymap(type))
#                    a              b                c              d
# ONE    <class 'str'>  <class 'str'>    <class 'str'>  <class 'str'>
# TWO    <class 'str'>  <class 'str'>  <class 'float'>  <class 'str'>
# THREE  <class 'str'>  <class 'str'>    <class 'str'>  <class 'str'>

dtypeを指定せずに読み込んだ後にastype()strにキャストした場合は欠損値も文字列'nan'に変換される。

df = pd.read_csv('data/src/sample_header_index_dtype.csv', index_col=0)
print(df.astype(str))
#        a    b      c  d
# ONE    1    1  100.0  x
# TWO    2   20    nan  y
# THREE  3  300  300.0  z

print(df.astype(str).applymap(type))
#                    a              b              c              d
# ONE    <class 'str'>  <class 'str'>  <class 'str'>  <class 'str'>
# TWO    <class 'str'>  <class 'str'>  <class 'str'>  <class 'str'>
# THREE  <class 'str'>  <class 'str'>  <class 'str'>  <class 'str'>

列ごとにデータ型dtypeを指定

引数dtypeには辞書(dict)で列の型を個別に指定することもできる。指定した列以外は自動で選ばれた型となる。

df_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
                     index_col=0, dtype={'a': float, 'b': str})
print(df_col)
#          a    b      c  d
# ONE    1.0  001  100.0  x
# TWO    2.0  020    NaN  y
# THREE  3.0  300  300.0  z

print(df_col.dtypes)
# a    float64
# b     object
# c    float64
# d     object
# dtype: object

辞書のキーは列番号でもよい。インデックス列を指定している場合、インデックス列も含めた列番号で指定する必要があるので注意。

df_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
                     index_col=0, dtype={1: float, 2: str})
print(df_col)
#          a    b      c  d
# ONE    1.0  001  100.0  x
# TWO    2.0  020    NaN  y
# THREE  3.0  300  300.0  z

print(df_col.dtypes)
# a    float64
# b     object
# c    float64
# d     object
# dtype: object

整数intが2進数や16進数で保存されているといった場合などは、read_csv()で文字列として読み込んだあとで所望の変換処理を行えばよい。以下の記事を参照。

欠損値NaNを含むCSVの読み込み

デフォルトで欠損値とみなされる値

read_csv()ではデフォルトでいくつかの値が欠損値NaNとみなされる。空文字列''や文字列'NaN''nan', 'null'など、考えられる値は概ね欠損値NaNとして扱われる。

By default the following values are interpreted as NaN: “ “, “#N/A”, “#N/A N/A”, “#NA”, “-1.#IND”, “-1.#QNAN”, “-NaN”, “-nan”, “1.#IND”, “1.#QNAN”, “<NA>”, “N/A”, “NA”, “NULL”, “NaN”, “None”, “n/a”, “nan”, “null “. pandas.read_csv — pandas 2.0.3 documentation

以下のファイルを例として動作を確認する。

,a,b
ONE,,NaN
TWO,-,nan
THREE,null,N/A

デフォルトで読み込んでisnull()メソッドで確認すると、対象外の'-'以外は欠損値NaNとして扱われていることが分かる。

df_nan = pd.read_csv('data/src/sample_header_index_nan.csv', index_col=0)
print(df_nan)
#          a   b
# ONE    NaN NaN
# TWO      - NaN
# THREE  NaN NaN

print(df_nan.isnull())
#            a     b
# ONE     True  True
# TWO    False  True
# THREE   True  True

pandas.DataFrameとして読み込んだあとの欠損値の処理については以下の記事を参照。

欠損値として扱う値を指定: 引数na_values, keep_default_na

欠損値として扱う値を指定するには、引数na_valuesを使う。上述のデフォルト値に加えて、引数na_valuesに指定した値も欠損値として扱われる。リストで複数の値を指定することもできる。

df_nan_set_na = pd.read_csv('data/src/sample_header_index_nan.csv',
                            index_col=0, na_values='-')
print(df_nan_set_na)
#         a   b
# ONE   NaN NaN
# TWO   NaN NaN
# THREE NaN NaN

print(df_nan_set_na.isnull())
#           a     b
# ONE    True  True
# TWO    True  True
# THREE  True  True

引数keep_default_naFalseとすると、上述のデフォルト値が欠損値として扱われなくなる。このとき引数na_valuesを指定すると、na_valuesに指定した値のみが欠損値として扱われる。

df_nan_no_keep = pd.read_csv('data/src/sample_header_index_nan.csv',
                             index_col=0, na_values=['-', 'NaN', 'null'],
                             keep_default_na=False)
print(df_nan_no_keep)
#          a    b
# ONE         NaN
# TWO    NaN  nan
# THREE  NaN  N/A

print(df_nan_no_keep.isnull())
#            a      b
# ONE    False   True
# TWO     True  False
# THREE   True  False

どの値も欠損値として扱わない: 引数na_filter

引数na_filterFalseとすると、引数na_values, keep_default_naによらずすべての値がそのままの文字列として読み込まれ、欠損値として扱われない。

df_nan_no_filter = pd.read_csv('data/src/sample_header_index_nan.csv',
                               index_col=0, na_filter=False)
print(df_nan_no_filter)
#           a    b
# ONE          NaN
# TWO       -  nan
# THREE  null  N/A

print(df_nan_no_filter.isnull())
#            a      b
# ONE    False  False
# TWO    False  False
# THREE  False  False

エンコーディングの指定: 引数encoding, encoding_errors

以下、Shift-JISでエンコードされたファイルを例とする。

エンコーディングは引数encodingで指定する。デフォルトはutf-8で、utf-8ではないファイルに対してはエラーUnicodeDecodeErrorになる。

# df_sjis = pd.read_csv('data/src/sample_header_shift_jis.csv')
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 8: invalid start byte

正しいエンコーディングを指定する必要がある。shift_jiscp932のファイルを扱う場合は注意。

df_sjis = pd.read_csv('data/src/sample_header_shift_jis.csv',
                      encoding='shift_jis')
print(df_sjis)
#    a   b   c   d
# 0  あ  12  13  14
# 1  い  22  23  24
# 2  う  32  33  34

引数encoding_errorsにエラー処理を指定できる。

デフォルトは'strict'で、上述のようにエラーになる。'ignore''replace'などを指定可能。

df_ignore = pd.read_csv('data/src/sample_header_shift_jis.csv',
                        encoding_errors='ignore')
print(df_ignore)
#     a   b   c   d
# 0 NaN  12  13  14
# 1 NaN  22  23  24
# 2 NaN  32  33  34

df_replace = pd.read_csv('data/src/sample_header_shift_jis.csv',
                         encoding_errors='replace')
print(df_replace)
#     a   b   c   d
# 0  ��  12  13  14
# 1  ��  22  23  24
# 2  ��  32  33  34

df_backslash = pd.read_csv('data/src/sample_header_shift_jis.csv',
                           encoding_errors='backslashreplace')
print(df_backslash)
#           a   b   c   d
# 0  \x82\xa0  12  13  14
# 1  \x82\xa2  22  23  24
# 2  \x82\xa4  32  33  34

ZIPなどで圧縮されたファイルの読み込み

read_csv()では、ZIPなどで圧縮されたCSVファイルをそのまま読み込むこともできる。

df_zip = pd.read_csv('data/src/sample_header.csv.zip')
print(df_zip)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

拡張子が.gz, .bz2, .zip, .xz, .zst, .tar, .tar.gz, .tar.xz, .tar.bz2の場合は、自動で検出して展開してくれる。拡張子が異なる場合は、引数compressionに文字列'zip'(ピリオドは不要)などを明示的に指定する。

なお、対応しているのはCSVファイル単体が圧縮されている場合のみ。複数ファイルが圧縮されている場合はエラーになる。

Web上のファイルの読み込み

これまでの例はローカルのファイルを指定してきたが、read_csv()の第一引数にはURLを指定することも可能。Web上のファイルを直接読み込める。ZIP圧縮されていてもよい。

GitHub上のCSVファイルを例とする。CSVファイル自体(Rawデータ)を示すURLでなければならないので注意。

df_web = pd.read_csv(
    'https://raw.githubusercontent.com/nkmk/python-snippets/master/notebook/data/src/sample_header.csv'
)
print(df_web)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

なお、多くの場合、引数を適宜指定しないと読み込めなかったり余計なデータが含まれてしまったりするので何度か試行する必要がある。特にサイズの大きいファイルの場合はローカルにダウンロードしてトライしたほうがいいかもしれない。

TSVファイルの読み込み: 引数sep

TSVファイル(タブ区切り)を読み込むには、read_csv()の引数sepにタブ文字\tを指定する。

    a   b   c   d
ONE 11  12  13  14
TWO 21  22  23  24
THREE   31  32  33  34
df_tsv_sep = pd.read_csv('data/src/sample_header_index.tsv', index_col=0, sep='\t')
print(df_tsv_sep)
#         a   b   c   d
# ONE    11  12  13  14
# TWO    21  22  23  24
# THREE  31  32  33  34

read_table()はデフォルトの区切り文字がタブ文字\tとなっている。引数などはread_csv()と同じ。

df_tsv = pd.read_table('data/src/sample_header_index.tsv', index_col=0)
print(df_tsv)
#         a   b   c   d
# ONE    11  12  13  14
# TWO    21  22  23  24
# THREE  31  32  33  34

関連カテゴリー

関連記事