Pythonで時系列分析の練習(3)PandasでCSVファイルの読み込み

Pythonで時系列分析の練習(3)PandasでCSVファイルの読み込み

Pythonで時系列分析する手法をモモノキ&ナノネと一緒に学習していきます。

モモノキ&ナノネと一緒にPythonで時系列分析を覚えよう(3)





PandasでCSVファイルのデータを取り込む方法

時系列分析の続きを始めるね。今回もPandasのキホン的な操作で、CSVファイルの扱い方を練習するよ。ナノネ、今回使うPandasだけインポートしておいて。

準備OK。

In [1]:
import pandas as pd

PandasでCSVファイルのデータを取り込むときは、read_csv([保存先パス]ファイル名)メソッドが使えるよ。癖のないシンプルなCSVファイルなら引数にファイル名を指定するだけで、データを取り込めるよ。CSVファイルがPython実行コードと別の場所に保存されている場合は、保存先のパスも必ず指定してね。
あと、URL形式でもCSVファイルが指定できる。ネット上のファイルも簡単に取り込めて便利なんだよ。

ナノネ、ローカルに読み込みテスト用のCSVファイルを一つ作ってみて。スプレットシートかテキストエディターで簡単に作れるから。読み込み練習なのでデータは適当でOKだよ。ファイルの保存場所はこのコードを動かしている場所と同じ階層に保存してね。

適当なデータでCSVファイルを一つ作成。
data.csvとういうファイル名で保存しといた。

OK、そのCSVファイルをPandasで読み込んでみよう。Pandasはpdという名前でインポートしているからメソッドの前にpd.をつけるよ。read_csvの戻り値はDataFrame型を返すので、変数で受け取る必要があるよ。

In [2]:
test_df = pd.read_csv('data.csv')
test_df # 表で中身を確認
Out[2]:
列1 列2 列3
0 2018-02-14 10 モモノキ
1 2018-02-15 20 ナノネ
2 2018-02-16 38 カキノキ
3 2018-02-17 14 モモノキ
4 2018-02-18 27 ナノネ
In [3]:
type(test_df) # 型の確認 => DataFrame
Out[3]:
pandas.core.frame.DataFrame

さっき作ったCSVファイルの中身一緒だ、うまく読み込めた。

注意点だけど、CSVファイルを読み込むときは文字コードの種類に注意してね。
ナノネはLinuxを使っているからデフォルトの文字コードがUTF-8で、さっき作ったCSVファイルもそのまま読み込めたけど。Windowsで作った場合やネットから入手したCSVファイルなどは、文字コードがUTF-8以外のケースがあるよ。その場合はファイルの形式に合った文字コードをオプション引数で指定する必要があるよ。

試しにWindowで作成したファイルを文字コード指定なしで読み込むと、こんな感じ。うまく読み取れないよ。

In [4]:
# test_df = pd.read_csv('data_shift-jis.csv') => Error
# ・・・省略
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0x97 in position 0: invalid start byte

Windowで普通に作成したファイルの場合、文字コードにSHIFT-JISを指定すれば問題なくデータを読み取れるよ。(encoding="SHIFT-JIS")

In [5]:
test_df = pd.read_csv('data_shift-jis.csv',
                       encoding="SHIFT-JIS") # 文字コード指定
test_df
Out[5]:
列1 列2 列3
0 2018-02-14 10 モモノキ
1 2018-02-15 20 ナノネ
2 2018-02-16 38 カキノキ
3 2018-02-17 14 モモノキ
4 2018-02-18 27 ナノネ

癖のあるCSVを読み込むとき、どうすればいいの?

ヘッダ行が無かったり、余分なヘッダが含まれている(数行目からデータが始まるなど)ケースなどがあるけど、オプション引数を設定すればうまく読み取れるよ。

In [6]:
test_df = pd.read_csv('data_no-header.csv',
                     header=None) # ヘッダ無しのCSV
test_df
Out[6]:
0 1 2
0 2018-02-14 10 モモノキ
1 2018-02-15 20 ナノネ
2 2018-02-16 38 カキノキ
3 2018-02-17 14 モモノキ
4 2018-02-18 27 ナノネ
In [7]:
test_df = pd.read_csv('data_no-header.csv',
                     header=None, # ヘッダ無しのCSV
                     names=['名前A', '名前B', '名前C']) # 列の名前を設定
test_df
Out[7]:
名前A 名前B 名前C
0 2018-02-14 10 モモノキ
1 2018-02-15 20 ナノネ
2 2018-02-16 38 カキノキ
3 2018-02-17 14 モモノキ
4 2018-02-18 27 ナノネ

CSVファイルの始めに余分な行が含まれている場合は、skiprowsで読み込みをスキップしたい行数が指定できるよ。

In [8]:
test_df = pd.read_csv('data_no-header.csv',
                      header=None,
                      skiprows=3) # CSVファイル先頭3行の読み込みスキップ
test_df
Out[8]:
0 1 2
0 2018-02-17 14 モモノキ
1 2018-02-18 27 ナノネ

他にも沢山のオプション引数が設定できるから、英語だけど必要に応じて公式マニュアルを調べてみてね。

Pandas公式マニュアル(外部サイト)
read_csv(公式マニュアル英語)

2回目の学習で、時系列データを扱うときはインデックスに日付を設定するように言ってたけど? CSVファイルを読み込むときに設定できるの?

オプション引数のindex_colにインデックスとして割り当てたいCSVデータ列を指定すればOKだよ。さっき作ったCSVの列1(列名)をインデックスに設定しみよう。
インデックス列は名前か列番で指定ができるよ。index_col='列1'もしくはindex_col=0してね。列番は0から数えるから注意ね。

In [9]:
test_df = pd.read_csv('data.csv') # インデックス指定なし
test_df # 表で中身を確認
Out[9]:
列1 列2 列3
0 2018-02-14 10 モモノキ
1 2018-02-15 20 ナノネ
2 2018-02-16 38 カキノキ
3 2018-02-17 14 モモノキ
4 2018-02-18 27 ナノネ
In [10]:
test_df = pd.read_csv('data.csv',
                      index_col='列1') # インデックス列を指定
test_df
Out[10]:
列2 列3
列1
2018-02-14 10 モモノキ
2018-02-15 20 ナノネ
2018-02-16 38 カキノキ
2018-02-17 14 モモノキ
2018-02-18 27 ナノネ

日付の入った列1がインデックスに設定されたみたい。これでOK?

日付インデックスは、もう一つ変更の必要だよ。ナノネ、インデクスのデータ型を確認してみて。データフレーム変数名.indexで型(dtype)が確認できるよ。

In [11]:
test_df.index
Out[11]:
Index(['2018-02-14', '2018-02-15', '2018-02-16', '2018-02-17', '2018-02-18'], dtype='object', name='列1')

dtypeがobjectになってる。ただの文字データ?

時系列分析の場合はインデックスを日付型としたいので、読み込むときに事前に変換しておこう。オプション引数のparse_datesで、日付型に変換したい列をリスト形式で指定すればOKだよ。列はインデクス同様に名前か列番で指定してね。

In [12]:
test_df = pd.read_csv('data.csv',
                      index_col='列1', # CSVの指定列をインデックスに設定
                      parse_dates=['列1'], # CSVの指定列を日付型に設定
                     ) 
#test_df
test_df.index # dytpe=datetime型
Out[12]:
DatetimeIndex(['2018-02-14', '2018-02-15', '2018-02-16', '2018-02-17',
               '2018-02-18'],
              dtype='datetime64[ns]', name='列1', freq=None)

インデックスのデータ型がdatetimeに変換できた。

日付データを読み込むときは、元データの表記にも注意してね。日付データはいろいろな表記が利用されているから。Pandas(Python)の標準表記以外の場合はパースが必要なケースがあるよ。日付は年月日を-で連結したYYYY-MM-DDが標準表記。/区切りなどは自動認識してくれるみたいだけど、年月日表記などはパースが必要そう。

日付をパースする方法はいろいろあるので、一例ね。オプション引数のdate_parserに日付変換用の自作関数やラムダ式を指定すると、parse_datesに指定した列の日付をうまく変換できるよ。
次の例はCSVデータの日付表記が○年□月△日の場合の変換方法だよ。

In [13]:
test_df = pd.read_csv('data-slash.csv') # オプションなしで、そのまま読み込み
print(test_df)
print((test_df['日付'].dtype)) # date列の型 => object
           日付  データ値
0  2017年11月2日    11
1  2017年12月5日    15
2   2018年1月1日    13
3  2018年2月18日    18
object
In [14]:
# /区切りの日付を変換するラムダ式
dateparse = lambda d: pd.datetime.strptime(d, '%Y年%m月%d日') 
test_df = pd.read_csv('data-slash.csv',
                      parse_dates=['日付'],
                      date_parser=dateparse) # 日付のパース方法は上で定義したラムダ式を指定
print(test_df)
print((test_df['日付'].dtype)) # date列の型 => datetime
          日付  データ値
0 2017-11-02    11
1 2017-12-05    15
2 2018-01-01    13
3 2018-02-18    18
datetime64[ns]

○年□月△日表記もうまく日付型に変化できた。

日付変換とインデックス指定を全部記載するとこんな感じ。データ値の型はdtypeで指定できるよ。時系列分析するときに必要だったね。

In [15]:
dateparse = lambda d: pd.datetime.strptime(d, '%Y年%m月%d日') 
test_df = pd.read_csv('data-slash.csv',
                      index_col='日付',
                      parse_dates=['日付'],
                      date_parser=dateparse, # 日付のパース方法は上で定義したラムダ式を指定
                      dtype='float') # データ型にfloatを指定
test_df
Out[15]:
データ値
日付
2017-11-02 11.0
2017-12-05 15.0
2018-01-01 13.0
2018-02-18 18.0

データはCSVファイルからDataFrameに取り込んだあとでも、変換や加工ができるので必要に応じてマニュアルなどを調べてみてね。

次回も、Pandasのキホン的な使い方をもう少しだけ練習をするね。

ラジャー。





スポンサーリンク

0 件のコメント :

コメントを投稿