Jupyter Notebook x Pandas
Page content
Jupyter Notebook x Pandas でデータ分析。 いろいろな tips をジャンルごとにまとめていくよぉ。
Jupyter Notebook x Pandas でデータ分析
let’s go.
Jupyter Notebook 一般系
notebook file から python script への変換
シェルスクリプトじゃないと出来ないようで大変遺憾ながら。
$ jupyter nbconvert --to script mynote.ipynb # -> mynote.py が生成される
もしくは notebook の最後のセルに以下を書く
import subprocess subprocess.run(['jupyter', 'nbconvert', '--to', 'python', 'ファイル名.ipynb'])
yaml.dump からファイルへの書き込みが壊れる
- work around: なぜだろう。ムカつく。だから
import yaml
はせず、yaml形式相当の文字列を作って、普通にファイル書き込みするようにしている。
notebook の結果をクリアするのはどうやる?
- どんどん
In [100]
みたいな大きな値になっちゃう。 - きれいに
In [1]
から始まるようにしたいなぁ。
DataFrame 操作系
DataFrame の扱いをまとめた チートシート
- 公式: https://github.com/pandas-dev/pandas/tree/master/doc/cheatsheet
- 日本語版: https://github.com/fan-s-katagiri/pandas-cheat-sheet-ja
- 日本語版応用編: https://qiita.com/s_katagiri/items/cc0bceddbbf84eb08d18
SettingWithCopyWarning という警告
- Seriesのサイズが大きいとメモリ空間の確保が膨大になるので警告が出るらしい。
- 最善の操作を勉強しないとなぁ。
pandas.DataFrame のインデックス参照で行・列を選択し取得
- 参考: https://note.nkmk.me/python-pandas-index-row-column/
- 学べそうなこと
- 特定の 行and列 の単独要素を取得: ``
- それを column name や index 値で:
- 任意の 行or列 を配列取得
DataFrame の行名・列名の変更
- rename(columns={今の列名1:新しい列名1, 今の列名2:新しい列名2})
df_new = df.rename(columns={'A': 'a'}, index={'ONE': 'one'}) print(df_new) # a B C # one 11 12 13 # TWO 21 22 23 # THREE 31 32 33 print(df) # A B C # ONE 11 12 13 # TWO 21 22 23 # THREE 31 32 33
DataFrame の結合
pd.concat([df1, df4], axis=1)
時系列データ系
Pandasで時刻データを扱うTimestampの使い方
- 参考: https://deepage.net/features/pandas-timestamp.html めちゃよくまとまっている
- PandasのTimestampクラスはPythonのdatetime.datetimeオブジェクトをPandasに移植したもので、よく使われる形式かなぁ。
- オブジェクトそのものの扱い方は
datetime.datetime
とほぼ一緒になる。
- オブジェクトそのものの扱い方は
- こいつを極めれば、時系列データを扱いやすくなりそう!
で、やってみているログ:
用語
- tz-native: timezone の概念がないデータ
- tz-aware: tz つきデータ
Timestamp クラスの主な関数
tz_localize('utc')
: 指定した tz で tz-aware に変える (Timestamp('2018-12-13 12:00')
をTimestamp('2018-12-13 12:00+00:00')
にする感じ)tz_convert('Asia/Tokyo')
: tz-aware なデータに対して指定した tz の表記に変換 (Timestamp('2018-12-13 12:00+00:00')
をTimestamp('2018-12-13 21:00+09:00')
に変換)tzinfo
: timezone 情報を取得する関数
offsets オブジェクト で時間を加減することができる!すげぇ! -> と思ったが timedelta とそんなにやってること変わらない。どちらが pandas の世界により馴染むか、というだけ
shiftによる日付の操作 は、時系列データ(indexをTimestamp型で構成したDataFrame)に対して、データの位置を指定の時間分ずらすことができる。
- 使い方
DataFrame.shift(ずらす数[, freq = ずらす単位])
- これで N-1 日の時系列データを +1 日シフトして、 N 日の時系列データと重ねて比較するのに一歩近づきそう。
- 使い方
時系列データの期間範囲指定
- 参考: https://qiita.com/terafon/items/6ec1ab28dcb261db2c73#%E6%9C%9F%E9%96%93%E3%82%92%E7%AF%84%E5%9B%B2%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B
- できること
- シンプルな例:
df1[df1['日付'] > dt.datetime(2019,5,3)]
- 応用的に、 AND 条件でいつからいつまで、とかも指定可能
- シンプルな例:
時系列データへの変換
- 要は index を datetime 型にしたいときの snippet:
df['date'] = pd.to_datetime(df['date']) df = df.set_index('date')
グラフ系
pandas の plot メソッドでグラフを作成しデータを可視化
- 参考: https://note.nkmk.me/python-pandas-plot/ この note.nkmk.me ってサイトよくまとまってるわ
- 学べそうなこと
- plot() メソッドの基礎
- サブプロットを活用した複数グラフの1画像集約
- いろんな形式の plot
- plot の共通書式の調整など
グラフを重ねる
- 1つは area chart で積み上げ、もう1個は line chart、これらを重ねて描画するにはこんな方法がお手軽:
fig = plt.figure(figsize=(16, 9)) ax = fig.add_subplot(1, 1, 1) df.plot.area(stacked=True, x='date', y=['A', 'B', 'C'], alpha=0.5, ax=ax) df.plot(x='date', y='ols', ax=ax)
分析系
最小二乗法 (OLS) による近似直線の導出
numpy の polyfit というメソッドで実現できる。
# 近似直線の傾き a, 切片 b を求める
a, b = np.polyfit(list(df.index), list(df['total']), 1)
df['ols'] = a * df.index + b