Python pandas 日本語環境向けのちょっとしたパッケージ作った
最近の空き時間は GitHub で草植えをしている。まずは pandas
を日本語環境で使う場合に たまに必要になる処理をまとめた パッケージを作った。
インストール
pip install japandas
機能
機能の一覧はこちら。
- 日時処理
- 日本語日付のパース
- 日本の祝日カレンダー
- 文字列処理
- Unicode 正規化
- 全角/半角変換
- リモートデータアクセス
詳細はドキュメントを。
日時処理
日本語日付のパース
pandas
には 日付らしい入力を適切に処理してくれる pandas.to_datetime
があるが、これは日本語の日付 ( "XX年XX月XX日" とか ) に対応していない。例えば 以下のような入力は日時としてパースされず 文字列のまま残ってしまう。
import pandas as pd pd.to_datetime(u'2014年11月30日') # u'2014年11月30日'
japandas.to_datetime
は pd.to_datetime
を軽くラップし、以下のような日付をパースできるようにする。
'XX年XX月XX日'
'XX年XX月'
'XX年XX月XX日XX時XX分'
'XX年XX月XX日XX時XX分XX秒'
import japandas as jpd jpd.to_datetime(u'2015年3月1日') # Timestamp('2015-03-01 00:00:00') jpd.to_datetime([u'2014年11月30日13時25分', u'2014年11月30日14時38分']) # <class 'pandas.tseries.index.DatetimeIndex'> # [2014-11-30 13:25:00, 2014-11-30 14:38:00] # Length: 2, Freq: None, Timezone: None
補足 リスト-like な入力を処理する場合、日付のフォーマットは全て同じでなければならない。
参考 標準の pd.to_datetime
で任意のフォーマットをパースするには、以下のように format
オプションで書式を与えてやればよい。pd.to_datetime
については、 Python pandas で日時関連のデータ操作をカンタンに - StatsFragments を。
pd.to_datetime(u'2014年11月30日', format=u'%Y年%m月%d日') # Timestamp('2014-11-30 00:00:00')
日本の祝日カレンダー
japandas.JapaneseHolidayCalendar
は日本の祝日を定義したクラス。
calendar = jpd.JapaneseHolidayCalendar() calendar.holidays() # <class 'pandas.tseries.index.DatetimeIndex'> # [1970-01-01, ..., 2030-12-23] # Length: 969, Freq: None, Timezone: None
このカレンダー定義を使うと、定義に応じた営業日計算が以下のとおりできる。
参考 Time Series / Date functionality — pandas 0.16.2 documentation
import datetime cday = pd.offsets.CDay(calendar=calendar) # 4/29は祝日(昭和の日)なので無視されて加算 datetime.datetime(2014, 4, 28) + cday # Timestamp('2014-04-30 00:00:00') # 4/26は土曜日, 4/27は日曜日なので無視されて減算 datetime.datetime(2014, 4, 28) - cday # Timestamp('2014-04-25 00:00:00') # 5/4は日曜日, 5/5は祝日(こどもの日), 5/6は祝日(みどりの日/振替休日)なので無視されて加算 datetime.datetime(2014, 5, 3) + cday # Timestamp('2014-05-07 00:00:00') # 5/3は土曜日、前日は営業日なので通常の減算 datetime.datetime(2014, 5, 3) - cday # Timestamp('2014-05-02 00:00:00')
また、作成した Custom Business Day インスタンスは 指定した範囲の営業日を含む Index
の生成にも使える。japandas.date_range
は pd.date_range
の日本語日付対応版。
indexer = jpd.date_range(u'2014年5月1日', u'2014年5月10日', freq=cday) indexer # <class 'pandas.tseries.index.DatetimeIndex'> # [2014-05-01, ..., 2014-05-09] # Length: 5, Freq: C, Timezone: None
この Index
を使うと、カレンダー定義に応じてデータを抽出する処理が簡単に書ける。
import numpy as np # 処理したいデータを作成 df = pd.DataFrame(np.random.randn(10, 3), index=jpd.date_range(u'2014年5月1日', u'2014年5月10日', freq='D')) df # 0 1 2 # 2014-05-01 0.762453 -1.418762 -0.150073 # 2014-05-02 0.966500 -0.473888 0.272871 # 2014-05-03 0.473370 -1.282504 0.380449 # 2014-05-04 0.215411 0.220587 -1.088699 # 2014-05-05 0.286348 -1.069165 -1.471871 # 2014-05-06 -0.665438 -0.402046 -1.008051 # 2014-05-07 1.173935 2.080087 -2.279285 # 2014-05-08 -0.957195 0.746798 0.092214 # 2014-05-09 -0.259276 -0.775489 0.572525 # 2014-05-10 -0.910188 0.294136 0.020730 # カレンダー上 営業日のレコードを抽出 df.loc[indexer] # 0 1 2 # 2014-05-01 0.762453 -1.418762 -0.150073 # 2014-05-02 0.966500 -0.473888 0.272871 # 2014-05-07 1.173935 2.080087 -2.279285 # 2014-05-08 -0.957195 0.746798 0.092214 # 2014-05-09 -0.259276 -0.775489 0.572525 # カレンダー上 休日のレコードを抽出 df[~df.index.isin(indexer)] # 0 1 2 # 2014-05-03 0.473370 -1.282504 0.380449 # 2014-05-04 0.215411 0.220587 -1.088699 # 2014-05-05 0.286348 -1.069165 -1.471871 # 2014-05-06 -0.665438 -0.402046 -1.008051 # 2014-05-10 -0.910188 0.294136 0.020730
文字列処理
Unicode 正規化
Series.str.normalize
を使うと、標準の unicodedata.normalize
と同じ処理を 各値に対して適用できる。
s = pd.Series([u'アイウエオ', u'カキクケコ', u'ガギグゲゴ', u'ABCDE']) s # 0 アイウエオ # 1 カキクケコ # 2 ガギグゲゴ # 3 ABCDE # dtype: object s.str.normalize() # 0 アイウエオ # 1 カキクケコ # 2 ガギグゲゴ # 3 ABCDE # dtype: object
文字列以外の値は np.nan
になる。これは str
アクセサの他のメソッドと一緒。また、 Python 2.x 系の str
( unicode
ではないもの) も処理できる。
s = pd.Series([u'アイウエオ', 23, u'ガギグゲゴ', None, 'AAA']) s.str.normalize() # 0 アイウエオ # 1 NaN # 2 ガギグゲゴ # 3 NaN # 4 AAA # dtype: object
全角/半角変換
正規化があればいらない気もするのだが、全角/半角変換用のメソッドもつけてみた。
Series.str.h2z
: 半角 -> 全角へ変換Series.str.z2h
: 全角 -> 半角へ変換
s = pd.Series([u'アイウエオ', u'ABC01', u'DE345']) z = s.str.h2z() z # 0 アイウエオ # 1 ABC01 # 2 DE345 # dtype: object z.str.z2h() # 0 アイウエオ # 1 ABC01 # 2 DE345 # dtype: object
参考 文字列処理全般については、 Python pandas で日時関連のデータ操作をカンタンに - StatsFragments を。
補足 全角/半角変換について、既存パッケージの実装は ベクトル化したとき少し遅くなりそうだったので再発明したのだが、速度的にはあまり意味はなかった。今後 既存パッケージに置き換えるか、Cython 化するかしたい 。また、str.normalize
は標準にのせたい 。
リモートデータアクセス
以下の記事の内容を pandas.io.data.DataReader
と同じ形式でラップしたもの。加えて .plot(kind='ohlc')
も可能。
参考 Remote Data Access — pandas 0.16.2 documentation
jpd.DataReader(7203, 'yahoojp', start='2014-10-01', end='2014-10-05') # 始値 高値 安値 終値 出来高 調整後終値* # 日付 # 2014-10-01 6450 6559 6435 6500 14482100 6500 # 2014-10-02 6370 6423 6256 6275 15240200 6275 # 2014-10-03 6231 6309 6217 6290 10280100 6290
補足 ページ取得の際は毎回ウェイトを入れている。あまり長期間のデータ取得には使わないよう。
最後に
不具合、もしくは日本固有の機能要望があれば GitHub からください。
Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理
- 作者: Wes McKinney,小林儀匡,鈴木宏尚,瀬戸山雅人,滝口開資,野上大介
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/12/26
- メディア: 大型本
- この商品を含むブログ (9件) を見る