はじめに
csvファイルを読み込みたいときは多々あると思います。
pythonでのcsvファイルの読み込み方。また、読み込んだデータの扱い方についてまとめていきます。
注意
この記事の中で読み込むCSVファイルは、以下のファイルとします。
ファイル名「TEST_STOCK.csv」。
コード,銘柄名,市場,始値,高値,安値,終値,出来高,売買代金
8111-T,Gウイン,東証1部,249.00,251.00,248.00,249.00,104000,25907000
8112-T,東スタイル,東証1部,1299.00,1319.00,1292.00,1312.00,132000,172590000
8113-T,ユニチャーム,東証1部,7100.00,7150.00,7020.00,7040.00,163500,1159842000
8114-T,デサント,東証1部,604.00,611.00,604.00,610.00,47000,28620000
8126-J,三光薬,JQ,324.00,324.00,322.00,322.00,4000,1294000
8127-T,ヤマトインタ,東証2部,1001.00,1019.00,1001.00,1019.00,800,810000
csv
まずは、pythonの標準ライブラリのcsvを使用してみます。
読み込み
csvを使用してcsvファイルを読み込むには以下のようにします。
import csv
csv_file = open("./TEST_STOCK.csv", "r", encoding="ms932")
#リスト形式
f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
辞書形式
f = csv.DictReader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
# もろもろの処理の後、close
csv_file.close()
このコードでは、csvファイルをopen関数で読み込みファイルオブジェクトを作成して、そのファイルオブジェクトをcsv.readerに読み込ませています。
こんなエラーが発生するかも
実行したときに、以下のようなエラーが発生する人もいるかもしれません。
AttributeError: module 'csv' has no attribute 'reader'
このエラーが発生したときは、csvライブラリが読み込まれていません。だいたい、自身がテスト実行しているpythonファイルのファイル名が「csv.py」になっているとかが原因なので、ファイル名を修正してやれば実行できます。
open使用時の注意
openを使用した場合は、必ずcloseしましょう。
しなくても、ガベージコレクションによってcloseされますが、closeされるか分からないので、予期しない動きになることがあります。
使用するタイミングが終わるとcloseするのが基本的なお作法になります。
ただ、closeするのを忘れることも多いかと思います。なので、openを使用するときは以下のようにwithを使用すると良いです。
withを使用すると、そのブロックが終了すると自動的にcloseを実施してくれます。
import csv
with open("./TEST_STOCK.csv", "r", encoding="ms932") as csv_file
#リスト形式
f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
#辞書形式
f = csv.DictReader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
各メソッドの説明
各メソッドの引数でよく使用すると思われるものをピックアップしてメモっておきます。
open
引数名 | 説明 |
---|---|
mode | どのようにファイルを読み込むのか指定する。 ’r’(読み込み用に開く。CSV読み込みならこの指定。) 'w'(書き込み用に開き、まずファイルを切り詰める。) 'x'(排他的な生成に開き、ファイルが存在する場合は失敗する。) 'a'(書き込み用に開き、ファイルが存在する場合は末尾に追記する。) |
encoding | CSVファイルの文字コードを指定する。例)ms932, utf_8 |
newline | universal newlines モードの動作を制御します。None, '', '\n', '\r', '\r\n' の指定が可能。 |
csv.reader or csv.DictReader
csv.reader、csv.DictReaderの違いは、返却される型です。ともに、イテレータ(iterator)プロトコルに対応したオブジェクトを返却しますが、CSVファイルの行の表現は、csv.readerはリスト型、csv.DictReaderは辞書型になります。
また、以下のパラメータは、厳密にいうと Dialect クラスの属性になります。
引数名 | 説明 | デフォルト |
---|---|---|
delimiter | フィールド間を分割するのに使用する文字。 | ','(カンマ) |
doublequote | フィールド内のquotecharがその文字自身である場合どのようにクオートするか。True の場合、この文字は二重化。 False の場合、 escapechar は quotechar の前に置かれます。 | True |
escapechar | エスケープ用の文字列をしてします。読み込み時、escapechar はそれに引き続く文字の特別な意味を取り除きます。 | None |
lineterminator | writerを使用する際に、各行の終端を表すのに使用する文字。readerでは、'\r' または '\n' を終端とするようにハードコードされているので関係ない。 | '\r\n' |
quotechar | delimiter や quotechar といった特殊文字を含むか、改行文字を含むフィールドをクオートする際に用いられる 1 文字からなる文字 | '"' |
skipinitialspace | True の場合、 delimiter の直後に続く空白は無視されます。 | False |
データの抽出方法
csv.reader
csv.reader で返却されるオブジェクトでのデータの抽出方法です。
イテレータ(iterator)プロトコルに対応したオブジェクトなのでfor文やnextで行データを取得することが可能です。
行データはリストなのでインデックスでアクセスできます。
f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
header = next(f)
print(header)
for row in f:
#rowはList
#row[0]で必要な項目を取得することができる
print(row)
['コード', '銘柄名', '市場', '始値', '高値', '安値', '終値', '出来高', '売買代金']
['8111-T', 'Gウイン', '東証1部', '249.00', '251.00', '248.00', '249.00', '104000', '25907000']
['8112-T', '東スタイル', '東証1部', '1299.00', '1319.00', '1292.00', '1312.00', '132000', '172590000']
['8113-T', 'ユニチャーム', '東証1部', '7100.00', '7150.00', '7020.00', '7040.00', '163500', '1159842000']
['8114-T', 'デサント', '東証1部', '604.00', '611.00', '604.00', '610.00', '47000', '28620000']
['8126-J', '三光薬', 'JQ', '324.00', '324.00', '322.00', '322.00', '4000', '1294000']
['8127-T', 'ヤマトインタ', '東証2部', '1001.00', '1019.00', '1001.00', '1019.00', '800', '810000']
csv.DictReader
csv.DictReader で返却されるオブジェクトでのデータの抽出方法です。
csv.readerの場合と同じく、イテレータ(iterator)プロトコルに対応したオブジェクトで返却されます。違うところは、行データが辞書型で表現されている点で、カラム名を指定して取得することができます。
f = csv.DictReader(csv_file)
for row in f:
#rowはdictionary
#row["column_name"] or row.get("column_name")で必要な項目を取得することができる
print(row)
OrderedDict([('コード', '8111-T'), ('銘柄名', 'Gウイン'), ('市場', '東証1部'), ('始値', '249.00'), ('高値', '251.00'), ('安値', '248.00'), ('終値', '249.00'), ('出来高', '104000'), ('売買代金', '25907000')])
OrderedDict([('コード', '8112-T'), ('銘柄名', '東スタイル'), ('市場', '東証1部'), ('始値', '1299.00'), ('高値', '1319.00'), ('安値', '1292.00'), ('終値', '1312.00'), ('出来高', '132000'), ('売買代金', '172590000')])
OrderedDict([('コード', '8113-T'), ('銘柄名', 'ユニチャーム'), ('市場', '東証1部'), ('始値', '7100.00'), ('高値', '7150.00'), ('安値', '7020.00'), ('終値', '7040.00'), ('出来高', '163500'), ('売買代金', '1159842000')])
OrderedDict([('コード', '8114-T'), ('銘柄名', 'デサント'), ('市場', '東証1部'), ('始値', '604.00'), ('高値', '611.00'), ('安値', '604.00'), ('終値', '610.00'), ('出来高', '47000'), ('売買代金', '28620000')])
OrderedDict([('コード', '8126-J'), ('銘柄名', '三光薬'), ('市場', 'JQ'), ('始値', '324.00'), ('高値', '324.00'), ('安値', '322.00'), ('終値', '322.00'), ('出来高', '4000'), ('売買代金', '1294000')])
OrderedDict([('コード', '8127-T'), ('銘柄名', 'ヤマトインタ'), ('市場', '東証2部'), ('始値', '1001.00'), ('高値', '1019.00'), ('安値', '1001.00'), ('終値', '1019.00'), ('出来高', '800'), ('売買代金', '810000')])
pandas
続いて使用してみるのは、pandasです。
pandasとは、データ分析用のライブラリです。データ分析のためのライブラリなので、データの取得に関しては専門ではありませんが、pandasで読み込んだデータはDataFrameオブジェクトとして読み込まれ読み込んだ後の操作がしやすいので少し紹介してみます。
読み込み
import pandas as pd
csv_input = pd.read_csv(filepath_or_buffer="D:\株価情報CSV\TEST_STOCK.csv", encoding="ms932", sep=",")
こんなエラーが発生するかも
実行するとこんなエラーが発生するかもしれません。
その場合は、引数に「engine="python"」を追加してください。するとエラーが出なくなります。
エラー自体は、ファイルのパス名(ファイル名かフォルダ)に日本語(たぶんマルチバイト文字)を含む場合に発生するようです。原因はよくわかりません。
OSError: Initializing from file failed
メソッドの説明
メソッド(read_csv)の引数でよく使用すると思われるものをピックアップしてメモっておきます。
read_csv
引数名 | 説明 | デフォルト |
---|---|---|
filepath_or_buffer | ファイルパスやreadメソッドをもったオブジェクトを指定します。 | None |
sep | 区切り文字です。 | ',' |
delimiter | 区切り文字。sep の代わりに delimiterでも区切り文字を指定可能。 | None |
encoding | CSVファイルの文字コードを指定する。例)ms932, utf_8 | None |
escapechar | エスケープ用の文字列をしてします。読み込み時、escapechar はそれに引き続く文字の特別な意味を取り除きます。 | None |
quotechar | delimiter や quotechar といった特殊文字を含むか、改行文字を含むフィールドをクオートする際に用いられる 1 文字からなる文字 | '"' |
データの抽出方法
pandasを使用してCSVファイルを読み込んだ場合、DataFrameオブジェクトが返却されます。
DataFrameオブジェクトは、2次元の表データを表現しています。列方向の見出しを列ラベル、行方向の見出しを行ラベルと呼びます。
DataFrameオブジェクトには、データを抽出する様々な方法が準備されています。その中で便利だなと思う方法を紹介していきます。
基本
import pandas as pd
csv_input = pd.read_csv(filepath_or_buffer="D:\株価情報CSV\TEST_STOCK.csv", encoding="ms932", sep=",")
# インプットの項目数(行数 * カラム数)を返却します。
print(csv_input.size)
# 指定したカラムだけ抽出したDataFrameオブジェクトを返却します。
print(csv_input[["コード", "銘柄名"]])
54
コード 銘柄名
0 8111-T Gウイン
1 8112-T 東スタイル
2 8113-T ユニチャーム
3 8114-T デサント
4 8126-J 三光薬
5 8127-T ヤマトインタ
value
#値を二次元配列形式?で返却します。
#返却される型は、numpy.ndarray
print(csv_input.values)
#行インデックス、カラムインデックスの順番で指定して項目の値を取得できます。
print(csv_input.values[0, 1])
[['8111-T' 'Gウイン' '東証1部' 249.0 251.0 248.0 249.0 104000 25907000]
['8112-T' '東スタイル' '東証1部' 1299.0 1319.0 1292.0 1312.0 132000 172590000]
['8113-T' 'ユニチャーム' '東証1部' 7100.0 7150.0 7020.0 7040.0 163500 1159842000]
['8114-T' 'デサント' '東証1部' 604.0 611.0 604.0 610.0 47000 28620000]
['8126-J' '三光薬' 'JQ' 324.0 324.0 322.0 322.0 4000 1294000]
['8127-T' 'ヤマトインタ' '東証2部' 1001.0 1019.0 1001.0 1019.0 800 810000]]
Gウイン
先頭から、後ろから
#頭から指定行数分取得
#返却される型は、pandas.core.frame.DataFrame
print(csv_input.head(3))
#後ろから指定行数分取得
#返却される型は、pandas.core.frame.DataFrame
print(csv_input.tail(3))
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
0 8111-T Gウイン 東証1部 249.0 251.0 248.0 249.0 104000 25907000
1 8112-T 東スタイル 東証1部 1299.0 1319.0 1292.0 1312.0 132000 172590000
2 8113-T ユニチャーム 東証1部 7100.0 7150.0 7020.0 7040.0 163500 1159842000
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
3 8114-T デサント 東証1部 604.0 611.0 604.0 610.0 47000 28620000
4 8126-J 三光薬 JQ 324.0 324.0 322.0 322.0 4000 1294000
5 8127-T ヤマトインタ 東証2部 1001.0 1019.0 1001.0 1019.0 800 810000
DataFrame情報
#行数を確認
print(len(csv_input))
#カラム数を確認
print(len(csv_input.columns))
#次元の確認
print(csv_input.shape)
6
9
(6, 9)
カラム情報
#カラム情報
print(csv_input.columns)
print(csv_input.columns[3])
Index(['コード', '銘柄名', '市場', '始値', '高値', '安値', '終値', '出来高', '売買代金'], dtype='object')
始値
データアクセスいろいろ
#データアクセスの方法いろいろ
#loc[rows, columns]
#全行選択の場合、rowsは「:」を指定
print(csv_input.loc[:,["始値", "終値"]])
print(csv_input.loc[1:2,["始値", "終値"]]) #2行目3行目
#iloc[rows番号, columns番号]
#全行選択の場合、rowsは「:」を指定
#インデックスの指定方法に注意
print(csv_input.iloc[:, 3]) #3カラム目を全行
print(csv_input.iloc[0:3, 3:5]) #3,4カラム目だけを1行~3行目まで抽出
#ix
#カラム名、カラム番号のどちらでも使用可能
print(csv_input.ix[0:3, ["始値", "終値", "安値"]]) #1行目~4行目
print(csv_input.ix[0:3, 3:6]) #1行目~3行目
始値 終値
0 249.0 249.0
1 1299.0 1312.0
2 7100.0 7040.0
3 604.0 610.0
4 324.0 322.0
5 1001.0 1019.0
始値 終値
1 1299.0 1312.0
2 7100.0 7040.0
0 249.0
1 1299.0
2 7100.0
3 604.0
4 324.0
5 1001.0
始値 高値
0 249.0 251.0
1 1299.0 1319.0
2 7100.0 7150.0
始値 終値 安値
0 249.0 249.0 248.0
1 1299.0 1312.0 1292.0
2 7100.0 7040.0 7020.0
3 604.0 610.0 604.0
始値 高値 安値
0 249.0 251.0 248.0
1 1299.0 1319.0 1292.0
2 7100.0 7150.0 7020.0
3 604.0 611.0 604.0
データの抽出
#指定した条件で抽出します
print(csv_input[csv_input["出来高"] > 100000])
#複数条件を組み合わせたい場合
#and条件は「&」を使用
print(csv_input[(csv_input["出来高"] > 100000) & (csv_input["終値"] >= csv_input["始値"])])
#or条件は「|」を使用
print(csv_input[(csv_input["出来高"] > 100000) | (csv_input["終値"] >= csv_input["始値"])])
#抽出条件には、以下のような指定方法もあります。
print(csv_input.query("出来高 > 100000"))
#複数の値を指定する
print(csv_input[(csv_input["銘柄名"].isin(["ユニチャーム", "デサント"]))])
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
0 8111-T Gウイン 東証1部 249.0 251.0 248.0 249.0 104000 25907000
1 8112-T 東スタイル 東証1部 1299.0 1319.0 1292.0 1312.0 132000 172590000
2 8113-T ユニチャーム 東証1部 7100.0 7150.0 7020.0 7040.0 163500 1159842000
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
0 8111-T Gウイン 東証1部 249.0 251.0 248.0 249.0 104000 25907000
1 8112-T 東スタイル 東証1部 1299.0 1319.0 1292.0 1312.0 132000 172590000
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
0 8111-T Gウイン 東証1部 249.0 251.0 248.0 249.0 104000 25907000
1 8112-T 東スタイル 東証1部 1299.0 1319.0 1292.0 1312.0 132000 172590000
2 8113-T ユニチャーム 東証1部 7100.0 7150.0 7020.0 7040.0 163500 1159842000
3 8114-T デサント 東証1部 604.0 611.0 604.0 610.0 47000 28620000
5 8127-T ヤマトインタ 東証2部 1001.0 1019.0 1001.0 1019.0 800 810000
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
0 8111-T Gウイン 東証1部 249.0 251.0 248.0 249.0 104000 25907000
1 8112-T 東スタイル 東証1部 1299.0 1319.0 1292.0 1312.0 132000 172590000
2 8113-T ユニチャーム 東証1部 7100.0 7150.0 7020.0 7040.0 163500 1159842000
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金
2 8113-T ユニチャーム 東証1部 7100.0 7150.0 7020.0 7040.0 163500 1159842000
3 8114-T デサント 東証1部 604.0 611.0 604.0 610.0 47000 28620000
列の追加
csv_input["追加カラム"] = ["TEST1", "TEST2", "TEST3", "TEST4", "TEST5", "TEST6"]
print(csv_input)
コード 銘柄名 市場 始値 高値 安値 終値 出来高 売買代金 追加カラム
0 8111-T Gウイン 東証1部 249.0 251.0 248.0 249.0 104000 25907000 TEST1
1 8112-T 東スタイル 東証1部 1299.0 1319.0 1292.0 1312.0 132000 172590000 TEST2
2 8113-T ユニチャーム 東証1部 7100.0 7150.0 7020.0 7040.0 163500 1159842000 TEST3
3 8114-T デサント 東証1部 604.0 611.0 604.0 610.0 47000 28620000 TEST4
4 8126-J 三光薬 JQ 324.0 324.0 322.0 322.0 4000 1294000 TEST5
5 8127-T ヤマトインタ 東証2部 1001.0 1019.0 1001.0 1019.0 800 810000 TEST6
以上。CSV読み込み以外のところにも結構触れましたが、私が忘れないためにも記述しておきます。