Python用データ分析ライブラリとしてデファクトスタンダードとなっているpandasの基本的な使い方について、まとめました。

本記事は、公式ドキュメント10 Minutes to pandasをベースに加筆・変更して記述しています。

ただし少しでも分かり易くする為に、元の記事をそのまま翻訳するのではなく、下記の点に留意した改善を加えています

  • 使用しているAPIのリファレンスを確認し易いように、出来るだけリファレンスへのリンクを併記
  • pandas実行環境が手元にない読者の方(電車の中でスマホで勉強中の方など)を意識して、処理前後で確認したくなるであろうデータの状態を出来るだけ都度表示
    • 公式「10 Minutes to pandas」は、同じDataFrameにどんどん処理をしていく形式を取っている箇所が多数あります。その為、処理前のDataFrameがどんな状態だったか、ずっと上までスクロールして戻って確認しなければならないことがあり、理解の妨げになることがあります。

備考

pandasやそのドキュメント等のライセンスについては、「データ分析ライブラリpandasのライセンス」に記載しています。

目次

1.   pandasについて

pandasは、高速で柔軟なデータ構造を提供するPythonパッケージです。Pythonで実用的なデータ分析をする際の、高水準な基盤となるべく開発されています。

pandasでは、様々な種類のデータを扱うことができます。

  • ExcelやSQLテーブルで扱われるような、複数の型が混在する表データ
  • 時系列のデータ(ソートされているもの、いないもの)
  • 行列データ
  • その他の観測データや統計データ

pandasの主要なデータ構造は、Series(1次元)とDataFrame(2次元)です。DataFrameは、Rで言うところのdata.frameに当たります。

pandasは、数値計算ライブラリNumPyの上に構築されていて、その他の科学計算系ライブラリと一緒に使うことを意図して開発されています。また高速に動作させる為、内部アルゴリズムはCythonやC言語で最適化・実装されています。

2.   前提としている環境

本記事では、下記を前提としています。

  • Python : Ver.3.x
  • pandas : Ver.0.21.0

3.   準備

慣習に習い、各種ライブラリを下記のようにインポートします。

1
2
3
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

4.   オブジェクトの生成[1]

4.1.   リストからSeriesを生成

pandasがデフォルトの整数インデックスを作成します。

1
2
s = pd.Series([1, 3, 5, np.nan, 6, 8])
s
0    1.0
1    3.0
2    5.0
3    NaN
4    6.0
5    8.0
dtype: float64

4.2.   日時のインデックスとラベル付きカラム(列)を持ったDataFrameを生成[25]

まず、date_range関数を使って、2017年1月1日から6日分のDatetimeIndexオブジェクトを作成します。

1
2
dates = pd.date_range('20170101', periods=6)
dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')

それをDataFrameのコンストラクタのindex引数に渡します。その他、引数は下記の通り渡します。

  • data引数(第1引数):NumPyrandn関数で生成した6x4の乱数の配列
  • index引数:DatetimeIndexオブジェクト
  • columns引数:リスト['A', 'B', 'C', 'D']
1
2
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

4.3.   辞書オブジェクトから、DataFrameを生成[24][25]

辞書オブジェクトの値一つ一つは、Seriesに変換できる形式である必要があります。

1
2
3
4
5
6
7
df2 = pd.DataFrame({ 'A' : 1.,
                     'B' : pd.Timestamp('20170102'),
                     'C' : pd.Series(1, index=list(range(4)), dtype='float32'),
                     'D' : np.array([3] * 4, dtype='int32'),
                     'E' : pd.Categorical(["test", "train", "test", "train"]),
                     'F' : 'foo' })
df2
A B C D E F
0 1.0 2017-01-02 1.0 3 test foo
1 1.0 2017-01-02 1.0 3 train foo
2 1.0 2017-01-02 1.0 3 test foo
3 1.0 2017-01-02 1.0 3 train foo

4.4.   出来上がったDataFrameの確認

各カラム(列)のデータ形式を確認します。

1
df2.dtypes
A           float64
B    datetime64[ns]
C           float32
D             int32
E          category
F            object
dtype: object

カラム(列)名は、そのままプロパティとしてアクセスすることができます。

2
df2.A
0    1.0
1    1.0
2    1.0
3    1.0
Name: A, dtype: float64
3
df2.B
0   2017-01-02
1   2017-01-02
2   2017-01-02
3   2017-01-02
Name: B, dtype: datetime64[ns]
4
df2.C
0    1.0
1    1.0
2    1.0
3    1.0
Name: C, dtype: float32
5
df2.D
0    3
1    3
2    3
3    3
Name: D, dtype: int32
6
df2.E
0     test
1    train
2     test
3    train
Name: E, dtype: category
Categories (2, object): [test, train]
7
df2.F
0    foo
1    foo
2    foo
3    foo
Name: F, dtype: object

5.   データの閲覧[2]

DataFrameの最初と最後を確認するには、headメソッドtailメソッドを使います。

5.1.   元のDataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

5.2.   DataFrameの最初の5行を表示

DataFrameの最初を確認するには、headメソッドを使います[27]。 引数を省略した場合は、5行目までが表示されます。

1
df.head()
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401

5.3.   DataFrameの最後の3行を表示

DataFrameの最後を確認するには、tailメソッドを使います[27]

1
df.tail(3)
A B C D
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

5.4.   インデックスを表示[23]

1
df.index
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')

5.5.   カラム(列)を表示[23]

1
df.columns
Index(['A', 'B', 'C', 'D'], dtype='object')

5.6.   値を表示

1
df.values
array([[ 0.4691, -0.2829, -1.5091, -1.1356],
       [ 1.2121, -0.1732,  0.1192, -1.0442],
       [-0.8618, -2.1046, -0.4949,  1.0718],
       [ 0.7216, -0.7068, -1.0396,  0.2719],
       [-0.425 ,  0.567 ,  0.2762, -1.0874],
       [-0.6737,  0.1136, -1.4784,  0.525 ]])

5.7.   統計的な概要を表示

DataFrame.describeメソッドを使います。

1
df.describe()
A B C D
count 6.000000 6.000000 6.000000 6.000000
mean 0.073711 -0.431125 -0.687758 -0.233103
std 0.843157 0.922818 0.779887 0.973118
min -0.861849 -2.104569 -1.509059 -1.135632
25% -0.611510 -0.600794 -1.368714 -1.076610
50% 0.022070 -0.228039 -0.767252 -0.386188
75% 0.658444 0.041933 -0.034326 0.461706
max 1.212112 0.567020 0.276232 1.071804

5.8.   DataFrameの転置[24]

DataFrame.Tプロパティで転置させることができます。

5.8.1.   元のDataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

5.8.2.   転置したDataFrame

DataFrame.Tプロパティで、行と列が入れ替わったDataFrameを取得できます。

1
df.T
2017-01-01 00:00:00 2017-01-02 00:00:00 2017-01-03 00:00:00 2017-01-04 00:00:00 2017-01-05 00:00:00 2017-01-06 00:00:00
A 0.469112 1.212112 -0.861849 0.721555 -0.424972 -0.673690
B -0.282863 -0.173215 -2.104569 -0.706771 0.567020 0.113648
C -1.509059 0.119209 -0.494929 -1.039575 0.276232 -1.478427
D -1.135632 -1.044236 1.071804 0.271860 -1.087401 0.524988

5.9.   インデックスやカラム(列)の並び替え

インデックスやカラム(列)を並び替えるには、DataFrame.sort_indexメソッドを使います。

  • axis引数に1を渡すと、カラム(列)を(行方向に)並び替えます。
  • axis引数に0を渡す(あるいは指定をしない)と、インデックスを(列方向に)並び替えます。
  • ascending引数にFalseを渡すと、降順に並び替えます。

5.9.1.   インデックスを降順に並び替え

1
df.sort_index(axis=0, ascending=False)
A B C D
2017-01-06 -0.673690 0.113648 -1.478427 0.524988
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632

5.9.2.   カラム(列)を降順に並び替え

1
df.sort_index(axis=1, ascending=False)
D C B A
2017-01-01 -1.135632 -1.509059 -0.282863 0.469112
2017-01-02 -1.044236 0.119209 -0.173215 1.212112
2017-01-03 1.071804 -0.494929 -2.104569 -0.861849
2017-01-04 0.271860 -1.039575 -0.706771 0.721555
2017-01-05 -1.087401 0.276232 0.567020 -0.424972
2017-01-06 0.524988 -1.478427 0.113648 -0.673690

5.10.   値の並び替え

値を並び替えるには、DataFrame.sort_valuesメソッドを使います[24]

  • axis引数に1を渡すと、カラム間で(行方向に)並び替えます。
  • axis引数に0を渡す(あるいは指定をしない)と、インデックス間で(列方向に)並び替えます。
  • ascending引数にFalseを渡すと、降順に並び替えます。

5.10.1.   カラム(列)「B」の値で昇順に並び替え

1
df.sort_values(by='B')
A B C D
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-06 -0.673690 0.113648 -1.478427 0.524988
2017-01-05 -0.424972 0.567020 0.276232 -1.087401

5.10.2.   カラム(列)「C」の値で降順に並び替え

1
df.sort_values(by='C', ascending=False)
A B C D
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-06 -0.673690 0.113648 -1.478427 0.524988
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632

6.   選択処理

6.1.   注意

インタラクティブな環境で使う場合など、標準的なpythonやNumPyの直感的な記法の方が便利な場合もありますが、製品コードではより最適化されているatプロパティiatプロパティlocプロパティilocプロパティ を使うことを、開発元は推奨しています。

6.2.   取得処理

6.2.1.   元の DataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

6.2.2.   カラム(列)名を1つ与えて、Seriesを生成 [23]

これは、df.Aと同等です。

1
df['A']
2017-01-01    0.469112
2017-01-02    1.212112
2017-01-03   -0.861849
2017-01-04    0.721555
2017-01-05   -0.424972
2017-01-06   -0.673690
Freq: D, Name: A, dtype: float64

カラム(列)名のリストを渡すと、それらのカラム(列)だけのDataFrameが返ってきます[24]

6.2.3.   スライスで、(行の)選択範囲を抽出[26]

6.2.3.1.   インデックスの0番目から3行分を抽出
1
df[0:3]
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
6.2.3.2.   インデックス「2017-01-02」から「2017-01-04」 までを抽出
1
df['20170102':'20170104']
A B C D
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860

6.3.   ラベルを使った選択[3]

6.3.1.   元のDataFrame を確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

datesも確認しておきます。

1
dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')

6.3.2.   locプロパティで行を抽出

DataFrame.locプロパティにインデックスの値を1つ渡して、その行を抽出します。

  • datesdfを作成する時に作ったインデックスです。
  • dates[0]は2017/1/1の0時0分を表すTimestampオブジェクトです。
1
df.loc[dates[0]]
A    0.469112
B   -0.282863
C   -1.509059
D   -1.135632
Name: 2017-01-01 00:00:00, dtype: float64

6.3.3.   locプロパティで行と列を抽出

DataFrame.locプロパティにインデックスのスライスとカラム(列)名のリストを渡して、行と列を絞り込みます。(":"は「全て」を表すスライスです)

1
df.loc[:, ['A','B']]
A B
2017-01-01 0.469112 -0.282863
2017-01-02 1.212112 -0.173215
2017-01-03 -0.861849 -2.104569
2017-01-04 0.721555 -0.706771
2017-01-05 -0.424972 0.567020
2017-01-06 -0.673690 0.113648

絞り込み結果には、渡したスライスの始まり(2017-01-02)と終わり(2017-01-04)が含まれます。

1
df.loc['20170102':'20170104', ['A','B']]
A B
2017-01-02 1.212112 -0.173215
2017-01-03 -0.861849 -2.104569
2017-01-04 0.721555 -0.706771

インデックスのラベルを1つだけ渡すと、Seriesが返ってきます。(2次元→1次元)

1
df.loc['20170102', ['A', 'B']]
A    1.212112
B   -0.173215
Name: 2017-01-02 00:00:00, dtype: float64

6.3.4.   locプロパティで値を取得[23]

DataFrame.locプロパティにインデックスとカラム(列)名を1つずつ渡すと、値が返ってきます。

1
df.loc[dates[0], 'A']
0.46911229990718628

6.3.5.   atプロパティで値を取得

値の取得にはDataFrame.atプロパティを使うこともできます。

1
df.at[dates[0], 'A']
0.46911229990718628

6.4.   位置(n番目)を使った選択[4]

6.4.1.   元のDataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

6.4.2.   位置で行を抽出

DataFrame.ilocプロパティに整数を1つ渡すと、その位置の行が返ってきます。

1
df.iloc[3]
A    0.721555
B   -0.706771
C   -1.039575
D    0.271860
Name: 2017-01-04 00:00:00, dtype: float64

6.4.3.   整数のスライスで選択

DataFrame.ilocプロパティに整数のスライスを渡すと、その範囲の行とカラム(列)が返ってきます。整数のスライスはNumPyやpythonと同様です。

1
df.iloc[3:5, 0:2]
A B
2017-01-04 0.721555 -0.706771
2017-01-05 -0.424972 0.567020

6.4.4.   整数のリストで選択[23]

DataFrame.ilocプロパティに整数のリストを渡すと、それらの位置の行とカラム(列)が返ってきます。

1
df.iloc[[1, 2, 4], [0, 2]]
A C
2017-01-02 1.212112 0.119209
2017-01-03 -0.861849 -0.494929
2017-01-05 -0.424972 0.276232

6.4.5.   行の位置だけで選択

カラム(列)の位置を":"にすることで、行の位置だけで選択できます。(カラム(列)の範囲を「全て」に指定できます)

1
df.iloc[1:3, :]
A B C D
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804

6.4.6.   カラム(列)の位置だけで選択

同様に、行の位置を":"にすることで、カラム(列)の位置だけで選択できます。(行の範囲を「全て」に指定できます)

1
df.iloc[:, 1:3]
B C
2017-01-01 -0.282863 -1.509059
2017-01-02 -0.173215 0.119209
2017-01-03 -2.104569 -0.494929
2017-01-04 -0.706771 -1.039575
2017-01-05 0.567020 0.276232
2017-01-06 0.113648 -1.478427

6.4.7.   行とカラム(列)の位置で値を取得

1
df.iloc[1, 1]
-0.17321464905330858

6.4.8.   iatプロパティで値を取得

値の取得にはDataFrame.iatプロパティを使うこともできます。

1
df.iat[1, 1]
-0.17321464905330858

6.5.   ブーリアン選択

6.5.1.   元のDataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

6.5.2.   ひとつのカラム(列)の値を使って選択

カラム(列)「A」の値が0より大きい行だけが返ってきます。

1
df[df.A > 0]
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-04 0.721555 -0.706771 -1.039575 0.271860

6.5.3.   条件に合う値のみを抽出[24][23]

この場合は、条件に合わない所はNaNになります。

1
df[df > 0]
A B C D
2017-01-01 0.469112 NaN NaN NaN
2017-01-02 1.212112 NaN 0.119209 NaN
2017-01-03 NaN NaN NaN 1.071804
2017-01-04 0.721555 NaN NaN 0.271860
2017-01-05 NaN 0.567020 0.276232 NaN
2017-01-06 NaN 0.113648 NaN 0.524988

6.5.4.   isinメソッドを使った選択

まず、動作確認用にdfにカラム(列)「E」を追加したdf2を作成します。

1
2
3
df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
df2
A B C D E
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632 one
2017-01-02 1.212112 -0.173215 0.119209 -1.044236 one
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804 two
2017-01-04 0.721555 -0.706771 -1.039575 0.271860 three
2017-01-05 -0.424972 0.567020 0.276232 -1.087401 four
2017-01-06 -0.673690 0.113648 -1.478427 0.524988 three

カラム(列)「E」の値が、Series.isinメソッドに渡したリスト['two', 'four']の要素と同じ行だけが返ってきます。

1
df2[df2['E'].isin(['two', 'four'])]
A B C D E
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804 two
2017-01-05 -0.424972 0.567020 0.276232 -1.087401 four

6.6.   値のセット

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632
2017-01-02 1.212112 -0.173215 0.119209 -1.044236
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804
2017-01-04 0.721555 -0.706771 -1.039575 0.271860
2017-01-05 -0.424972 0.567020 0.276232 -1.087401
2017-01-06 -0.673690 0.113648 -1.478427 0.524988

datesも確認しておきます。

1
dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')

6.6.1.   新しいカラム(列)に値をセット

まず、下記のようなSeriesオブジェクトs1を作成します。

1
2
s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20170102', periods=6))
s1
2017-01-02    1
2017-01-03    2
2017-01-04    3
2017-01-05    4
2017-01-06    5
2017-01-07    6
Freq: D, dtype: int64

dfのカラム(列)「F」にs1をセットすると、自動的にインデックスに合わせて値が格納されます。

1
2
df['F'] = s1
df
A B C D F
2017-01-01 0.469112 -0.282863 -1.509059 -1.135632 NaN
2017-01-02 1.212112 -0.173215 0.119209 -1.044236 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804 2.0
2017-01-04 0.721555 -0.706771 -1.039575 0.271860 3.0
2017-01-05 -0.424972 0.567020 0.276232 -1.087401 4.0
2017-01-06 -0.673690 0.113648 -1.478427 0.524988 5.0

6.6.2.   ラベル指定で値をセット

1
2
df.at[dates[0], 'A'] = 0
df
A B C D F
2017-01-01 0.000000 -0.282863 -1.509059 -1.135632 NaN
2017-01-02 1.212112 -0.173215 0.119209 -1.044236 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804 2.0
2017-01-04 0.721555 -0.706771 -1.039575 0.271860 3.0
2017-01-05 -0.424972 0.567020 0.276232 -1.087401 4.0
2017-01-06 -0.673690 0.113648 -1.478427 0.524988 5.0

6.6.3.   位置指定で値をセット

1
2
df.iat[0,1] = 0
df
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 -1.135632 NaN
2017-01-02 1.212112 -0.173215 0.119209 -1.044236 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 1.071804 2.0
2017-01-04 0.721555 -0.706771 -1.039575 0.271860 3.0
2017-01-05 -0.424972 0.567020 0.276232 -1.087401 4.0
2017-01-06 -0.673690 0.113648 -1.478427 0.524988 5.0

6.6.4.   NumPy配列の値をセット

まず、下記のようなNumPy配列を作成します。

1
np.array([5] * len(df))
array([5, 5, 5, 5, 5, 5])

それをカラム(列)「D」にセットします。

1
2
df.loc[:, 'D'] = np.array([5] * len(df))
df
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 5 NaN
2017-01-02 1.212112 -0.173215 0.119209 5 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0
2017-01-05 -0.424972 0.567020 0.276232 5 4.0
2017-01-06 -0.673690 0.113648 -1.478427 5 5.0

6.6.5.   条件に合う値だけを上書き

正の値を全て負にします。

1
2
3
df2 = df.copy()
df2[df2 > 0] = -df2
df2
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 -5 NaN
2017-01-02 -1.212112 -0.173215 -0.119209 -5 -1.0
2017-01-03 -0.861849 -2.104569 -0.494929 -5 -2.0
2017-01-04 -0.721555 -0.706771 -1.039575 -5 -3.0
2017-01-05 -0.424972 -0.567020 -0.276232 -5 -4.0
2017-01-06 -0.673690 -0.113648 -1.478427 -5 -5.0

7.   不明値(欠測値)(NaN)[5]

pandasでは、不明値(欠測値)を表現するのに主にNumPyのNaN(np.nan)を使います。基本的にNaNは計算処理の対象外になります。

7.1.   元のDataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 5 NaN
2017-01-02 1.212112 -0.173215 0.119209 5 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0
2017-01-05 -0.424972 0.567020 0.276232 5 4.0
2017-01-06 -0.673690 0.113648 -1.478427 5 5.0

datesも確認しておきます。

1
dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')

7.2.   行・カラム(列)の変更/追加/削除

DataFrame.reindexメソッドを使えば、行あるいはカラム(列)を変更/追加/削除することができます。DataFrame.reindexメソッドは、元のDataFrameから作ったコピーを返します。 (元のDataFrameは書き換えられません)

新しくできたセルには、NaNが入ります。

1
df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])
A B C D F E
2017-01-01 0.000000 0.000000 -1.509059 5 NaN NaN
2017-01-02 1.212112 -0.173215 0.119209 5 1.0 NaN
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0 NaN
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0 NaN

新しくできたセルの一部に1をセットします。

1
2
3
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])
df1.loc[dates[0]:dates[1], 'E'] = 1
df1
A B C D F E
2017-01-01 0.000000 0.000000 -1.509059 5 NaN 1.0
2017-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0 NaN
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0 NaN

7.3.   不明値(欠測値)の削除[24][23]

DataFrame.dropnaメソッドで不明値(欠測値)NaNが存在する行を削除します。

1
df1.dropna(how='any')
A B C D F E
2017-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0

DataFrame.fillnaメソッドで不明値(欠測値)NaNを5で埋めます。

1
df1.fillna(value=5)
A B C D F E
2017-01-01 0.000000 0.000000 -1.509059 5 5.0 1.0
2017-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0 5.0
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0 5.0

DataFrame.isnaメソッドは、各セルが不明値(欠測値)NaNかどうかをTrueFalseで返します。

1
pd.isna(df1)
A B C D F E
2017-01-01 False False False False True False
2017-01-02 False False False False False False
2017-01-03 False False False False False True
2017-01-04 False False False False False True

8.   演算処理[6]

8.1.   統計値

演算処理は、基本的に不明値(欠測値)NaNを除外して行われます。

8.1.1.   元の DataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 5 NaN
2017-01-02 1.212112 -0.173215 0.119209 5 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0
2017-01-05 -0.424972 0.567020 0.276232 5 4.0
2017-01-06 -0.673690 0.113648 -1.478427 5 5.0

datesも確認しておきます。

1
dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')

8.1.2.   平均値の取得

DataFrame.meanメソッドで各カラム(列)の数値の平均値が返ってきます。

1
df.mean()
A   -0.004474
B   -0.383981
C   -0.687758
D    5.000000
F    3.000000
dtype: float64

DataFrame.meanメソッドの引数に1を渡すとカラム間の(行方向の)平均値が返ってきます。

1
df.mean(1)
2017-01-01    0.872735
2017-01-02    1.431621
2017-01-03    0.707731
2017-01-04    1.395042
2017-01-05    1.883656
2017-01-06    1.592306
Freq: D, dtype: float64

もう少し明示的に書くと下記のようになります。

1
df.mean(axis=1)
2017-01-01    0.872735
2017-01-02    1.431621
2017-01-03    0.707731
2017-01-04    1.395042
2017-01-05    1.883656
2017-01-06    1.592306
Freq: D, dtype: float64

8.1.3.   異なる次元のオブジェクト間の演算

異なる次元のオブジェクト間で演算をする場合、pandasは指定した方向に自動的に演算を展開します。

まず下記のようなSeriesを作ります。

1
2
s = pd.Series([1,3,4,np.nan,6,8], index=dates).shift(2)
s
2017-01-01    NaN
2017-01-02    NaN
2017-01-03    1.0
2017-01-04    3.0
2017-01-05    4.0
2017-01-06    NaN
Freq: D, dtype: float64

これは、下記のようなSeriesを、Series.shiftメソッドでインデックスを2日ずらしたSeriesです。

1
pd.Series([1,3,4,np.nan,6,8], index=dates)
2017-01-01    1.0
2017-01-02    3.0
2017-01-03    4.0
2017-01-04    NaN
2017-01-05    6.0
2017-01-06    8.0
Freq: D, dtype: float64

これをDataFrame.subメソッドを使って、DataFrameから引きます。

1
df.sub(s, axis='index')
A B C D F
2017-01-01 NaN NaN NaN NaN NaN
2017-01-02 NaN NaN NaN NaN NaN
2017-01-03 -1.861849 -3.104569 -1.494929 4.0 1.0
2017-01-04 -2.278445 -3.706771 -4.039575 2.0 0.0
2017-01-05 -4.424972 -3.432980 -3.723768 1.0 0.0
2017-01-06 NaN NaN NaN NaN NaN

8.2.   関数の適用

8.2.1.   元の DataFrameを確認

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 5 NaN
2017-01-02 1.212112 -0.173215 0.119209 5 1.0
2017-01-03 -0.861849 -2.104569 -0.494929 5 2.0
2017-01-04 0.721555 -0.706771 -1.039575 5 3.0
2017-01-05 -0.424972 0.567020 0.276232 5 4.0
2017-01-06 -0.673690 0.113648 -1.478427 5 5.0

8.2.2.   各カラム(列)への関数の適用

DataFrame.apply メソッドに関数を渡すと、各データにその関数を適用することができます。下記の例では、各カラム(列)のSeriesNumPyのcumsum関数を適用して、累積和にしています。

1
df.apply(np.cumsum)
A B C D F
2017-01-01 0.000000 0.000000 -1.509059 5 NaN
2017-01-02 1.212112 -0.173215 -1.389850 10 1.0
2017-01-03 0.350263 -2.277784 -1.884779 15 3.0
2017-01-04 1.071818 -2.984555 -2.924354 20 6.0
2017-01-05 0.646846 -2.417535 -2.648122 25 10.0
2017-01-06 -0.026844 -2.303886 -4.126549 30 15.0

8.3.   ヒストグラム化[7]

ヒストグラム化には、Series.value_countsメソッドを使います。

例としてまずランダムな整数値のSeriesを作成します。

1
2
s = pd.Series(np.random.randint(0, 7, size=10))
s
0    4
1    2
2    1
3    2
4    6
5    4
6    4
7    6
8    4
9    4
dtype: int64

Series.value_countsメソッドは、各値が何回ずつ登場するのかを返してくれます。

1
s.value_counts()
4    5
6    2
2    2
1    1
dtype: int64

8.4.   文字列処理[8]

Seriesは文字列処理の為のstrアクセサを備えています。

例を示す為にまず文字列を値として持つSeriesを作成します。

1
2
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s
0       A
1       B
2       C
3    Aaba
4    Baca
5     NaN
6    CABA
7     dog
8     cat
dtype: object

例えばSeries.str.lowerメソッドは文字列を小文字にします。

1
s.str.lower()
0       a
1       b
2       c
3    aaba
4    baca
5     NaN
6    caba
7     dog
8     cat
dtype: object

9.   マージ

9.1.   連結(concat)[9]

SeriesDataFramePanelを連結するのには、concat関数を使います。

例を示す為にまずは下記のようなDataFrameを用意します。

1
2
df = pd.DataFrame(np.random.randn(10, 4))
df
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495

dfの一部を要素に持つリストを作ります。

1
2
pieces = [df[:3], df[3:7], df[7:]]
pieces
[          0         1         2         3
 0 -0.548702  1.467327 -1.015962 -0.483075
 1  1.637550 -1.217659 -0.291519 -1.745505
 2 -0.263952  0.991460 -0.919069  0.266046,
           0         1         2         3
 3 -0.709661  1.669052  1.037882 -1.705775
 4 -0.919854 -0.042379  1.247642 -0.009920
 5  0.290213  0.495767  0.362949  1.548106
 6 -1.131345 -0.089329  0.337863 -0.945867,
           0         1         2         3
 7 -0.932132  1.956030  0.017587 -0.016692
 8 -0.575247  0.254161 -1.143704  0.215897
 9  1.193555 -0.077118 -0.408530 -0.862495]

リストの各要素を確認すると、こうなっています。

1
pieces[0]
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
1
pieces[1]
0 1 2 3
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
1
pieces[2]
0 1 2 3
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495

concat関数にこのリストを渡すと、各要素を連結したDataFrameを返します。[25]

1
pd.concat(pieces)
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495

9.2.   結合(join)[10]

SQLスタイルのマージには、merge関数を使います。

1
2
left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]})
left
key lval
0 foo 1
1 bar 2
1
2
right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})
right
key rval
0 foo 4
1 bar 5

keyカラム(列)を基準にしてマージします。

1
pd.merge(left, right, on='key')
key lval rval
0 foo 1 4
1 bar 2 5

9.3.   追加[11]

DataFrameに行を追加するのには、DataFrame.appendメソッドを使います。

例を示す為にまずは下記のようなDataFrameSeriesを用意します。

1
2
df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])
df
A B C D
0 1.346061 1.511763 1.627081 -0.990582
1 -0.441652 1.211526 0.268520 0.024580
2 -1.577585 0.396823 -0.105381 -0.532532
3 1.453749 1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346 0.339969 -0.693205
5 -0.339355 0.593616 0.884345 1.591431
6 0.141809 0.220390 0.435589 0.192451
7 -0.096701 0.803351 1.715071 -0.708758
1
2
s = df.iloc[3]
s
A    1.453749
B    1.208843
C   -0.080952
D   -0.264610
Name: 3, dtype: float64

DataFrame.appendメソッドを使って、インデックスを無視してDataFrameSeriesを追加します。[23]

1
df.append(s, ignore_index=True)
A B C D
0 1.346061 1.511763 1.627081 -0.990582
1 -0.441652 1.211526 0.268520 0.024580
2 -1.577585 0.396823 -0.105381 -0.532532
3 1.453749 1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346 0.339969 -0.693205
5 -0.339355 0.593616 0.884345 1.591431
6 0.141809 0.220390 0.435589 0.192451
7 -0.096701 0.803351 1.715071 -0.708758
8 1.453749 1.208843 -0.080952 -0.264610

DataFrame.appendメソッドを使って、インデックスを無視せずにDataFrameSeriesを追加します。[23]

1
df.append(s, ignore_index=False)
A B C D
0 1.346061 1.511763 1.627081 -0.990582
1 -0.441652 1.211526 0.268520 0.024580
2 -1.577585 0.396823 -0.105381 -0.532532
3 1.453749 1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346 0.339969 -0.693205
5 -0.339355 0.593616 0.884345 1.591431
6 0.141809 0.220390 0.435589 0.192451
7 -0.096701 0.803351 1.715071 -0.708758
3 1.453749 1.208843 -0.080952 -0.264610

10.   グルーピング(グループ化)[12]

pandasで言うところの「グルーピング(Group By)」とは、下記の一つ以上の手順を含む処理のことです。

  • ある基準に従って、データをグループに分割すること
  • 各グループに関数を個別に適用すること
  • その結果を結合して1つのデータ構造にすること

例を示す為にまずは下記のようなDataFrameを用意します。

1
2
3
4
5
6
7
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                          'foo', 'bar', 'foo', 'foo'],
                   'B' : ['one', 'one', 'two', 'three',
                          'two', 'two', 'one', 'three'],
                   'C' : np.random.randn(8),
                   'D' : np.random.randn(8)})
df
A B C D
0 foo one -1.202872 -0.055224
1 bar one -1.814470 2.395985
2 foo two 1.018601 1.552825
3 bar three -0.595447 0.166599
4 foo two 1.395433 0.047609
5 bar two -0.392670 -0.136473
6 foo one 0.007207 -0.561757
7 foo three 1.928123 -1.623033

カラム(列)「A」の値でデータをグルーピングし、その結果にGroupBy.sumメソッドを適用します。

1
df.groupby('A').sum()
C D
A
bar -2.802588 2.42611
foo 3.146492 -0.63958

複数のカラム(列)でグルーピングすると、関数を適用した時点でマルチインデックスになります。

1
df.groupby(['A', 'B']).sum()
C D
A B
bar one -1.814470 2.395985
three -0.595447 0.166599
two -0.392670 -0.136473
foo one -1.195665 -0.616981
three 1.928123 -1.623033
two 2.414034 1.600434

11.   構成変更(リシェイプ)[13][14]

11.1.   スタック

例を示す為にまずは下記のようなDataFrameを用意します。

1
2
3
4
5
tuples = list(zip(*[['bar', 'bar', 'baz', 'baz',
                     'foo', 'foo', 'qux', 'qux'],
                    ['one', 'two', 'one', 'two',
                     'one', 'two', 'one', 'two']]))
tuples
[('bar', 'one'),
 ('bar', 'two'),
 ('baz', 'one'),
 ('baz', 'two'),
 ('foo', 'one'),
 ('foo', 'two'),
 ('qux', 'one'),
 ('qux', 'two')]
1
2
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
index
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
           names=['first', 'second'])
1
2
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
df
A B
first second
bar one 0.029399 -0.542108
two 0.282696 -0.087302
baz one -1.575170 1.771208
two 0.816482 1.100230
foo one -0.612665 1.586976
two 0.019234 0.264294
qux one 1.074803 0.173520
two 0.211027 1.357138

dfから下記のようにdf2を作ります。

1
2
df2 = df[:4]
df2
A B
first second
bar one 0.029399 -0.542108
two 0.282696 -0.087302
baz one -1.575170 1.771208
two 0.816482 1.100230

DataFrame.stack メソッドは、カラム(列)をマルチインデックスの1つの階層(レベル)に"圧縮"します。

1
2
stacked = df2.stack()
stacked
first  second
bar    one     A    0.029399
               B   -0.542108
       two     A    0.282696
               B   -0.087302
baz    one     A   -1.575170
               B    1.771208
       two     A    0.816482
               B    1.100230
dtype: float64

インデックスを確認すると、こうなっています。

1
stacked.index
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two'], ['A', 'B']],
           labels=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 1, 1, 0, 0, 1, 1], [0, 1, 0, 1, 0, 1, 0, 1]],
           names=['first', 'second', None])

マルチインデックスを持つ"スタックされた"DataFrameSeriesに対して、DataFrame.unstack メソッド(DataFrame.stackメソッドとは逆の操作)をすると、こうなります。デフォルトでは、最後の階層(レベル)をカラム(列)にします。

1
stacked.unstack()
A B
first second
bar one 0.029399 -0.542108
two 0.282696 -0.087302
baz one -1.575170 1.771208
two 0.816482 1.100230

階層(レベル)を指定するとこうなります。

1
stacked.unstack(1)
second one two
first
bar A 0.029399 0.282696
B -0.542108 -0.087302
baz A -1.575170 0.816482
B 1.771208 1.100230
1
stacked.unstack(0)
first bar baz
second
one A 0.029399 -1.575170
B -0.542108 1.771208
two A 0.282696 0.816482
B -0.087302 1.100230

11.2.   ピボットテーブル[15]

例を示す為にまずは下記のようなDataFrameを用意します。

1
2
3
4
5
6
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
                   'B' : ['A', 'B', 'C'] * 4,
                   'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
                   'D' : np.random.randn(12),
                   'E' : np.random.randn(12)})
df
A B C D E
0 one A foo 1.418757 -0.179666
1 one B foo -1.879024 1.291836
2 two C foo 0.536826 -0.009614
3 three A bar 1.006160 0.392149
4 one B bar -0.029716 0.264599
5 one C bar -1.146178 -0.057409
6 two A foo 0.100900 -1.425638
7 three B foo -1.035018 1.024098
8 one C foo 0.314665 -0.106062
9 one A bar -0.773723 1.824375
10 two B bar -1.170653 0.595974
11 three C bar 0.648740 1.167115

所謂ピボットテーブルを作るのには、pivot_table関数を使います。

この例では、下記のようにカラム(列)名を指定しています。

  • カラム(列)「A」と「B」をインデックスに。
  • カラム(列)「C」の値を、新たなカラムに。
  • カラム(列)「D」の値を、データとして各値に。
1
pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
C bar foo
A B
one A -0.773723 1.418757
B -0.029716 -1.879024
C -1.146178 0.314665
three A 1.006160 NaN
B NaN -1.035018
C 0.648740 NaN
two A NaN 0.100900
B -1.170653 NaN
C NaN 0.536826

以下、記述中。


12.   日時の処理[16]

pandasには、シンプルで強力で且つ効率的な、時間の頻度変換の機能を備えています。時間の頻度変換とは例えば、1秒毎のデータを5分毎のデータにする、というような変換のことです。

例を示す為に、date_range関数を使って下記のようなDatetimeIndexを作ります。これは2017/1/1の0時0分0秒から1秒毎に100個(つまり99秒後まで)の要素を持ちます。

1
2
rng = pd.date_range('1/1/2017', periods=100, freq='S')
rng
DatetimeIndex(['2017-01-01 00:00:00', '2017-01-01 00:00:01',
               '2017-01-01 00:00:02', '2017-01-01 00:00:03',
               '2017-01-01 00:00:04', '2017-01-01 00:00:05',
               '2017-01-01 00:00:06', '2017-01-01 00:00:07',
               '2017-01-01 00:00:08', '2017-01-01 00:00:09',
               '2017-01-01 00:00:10', '2017-01-01 00:00:11',
               '2017-01-01 00:00:12', '2017-01-01 00:00:13',
               '2017-01-01 00:00:14', '2017-01-01 00:00:15',
               '2017-01-01 00:00:16', '2017-01-01 00:00:17',
               '2017-01-01 00:00:18', '2017-01-01 00:00:19',
               '2017-01-01 00:00:20', '2017-01-01 00:00:21',
               '2017-01-01 00:00:22', '2017-01-01 00:00:23',
               '2017-01-01 00:00:24', '2017-01-01 00:00:25',
               '2017-01-01 00:00:26', '2017-01-01 00:00:27',
               '2017-01-01 00:00:28', '2017-01-01 00:00:29',
               '2017-01-01 00:00:30', '2017-01-01 00:00:31',
               '2017-01-01 00:00:32', '2017-01-01 00:00:33',
               '2017-01-01 00:00:34', '2017-01-01 00:00:35',
               '2017-01-01 00:00:36', '2017-01-01 00:00:37',
               '2017-01-01 00:00:38', '2017-01-01 00:00:39',
               '2017-01-01 00:00:40', '2017-01-01 00:00:41',
               '2017-01-01 00:00:42', '2017-01-01 00:00:43',
               '2017-01-01 00:00:44', '2017-01-01 00:00:45',
               '2017-01-01 00:00:46', '2017-01-01 00:00:47',
               '2017-01-01 00:00:48', '2017-01-01 00:00:49',
               '2017-01-01 00:00:50', '2017-01-01 00:00:51',
               '2017-01-01 00:00:52', '2017-01-01 00:00:53',
               '2017-01-01 00:00:54', '2017-01-01 00:00:55',
               '2017-01-01 00:00:56', '2017-01-01 00:00:57',
               '2017-01-01 00:00:58', '2017-01-01 00:00:59',
               '2017-01-01 00:01:00', '2017-01-01 00:01:01',
               '2017-01-01 00:01:02', '2017-01-01 00:01:03',
               '2017-01-01 00:01:04', '2017-01-01 00:01:05',
               '2017-01-01 00:01:06', '2017-01-01 00:01:07',
               '2017-01-01 00:01:08', '2017-01-01 00:01:09',
               '2017-01-01 00:01:10', '2017-01-01 00:01:11',
               '2017-01-01 00:01:12', '2017-01-01 00:01:13',
               '2017-01-01 00:01:14', '2017-01-01 00:01:15',
               '2017-01-01 00:01:16', '2017-01-01 00:01:17',
               '2017-01-01 00:01:18', '2017-01-01 00:01:19',
               '2017-01-01 00:01:20', '2017-01-01 00:01:21',
               '2017-01-01 00:01:22', '2017-01-01 00:01:23',
               '2017-01-01 00:01:24', '2017-01-01 00:01:25',
               '2017-01-01 00:01:26', '2017-01-01 00:01:27',
               '2017-01-01 00:01:28', '2017-01-01 00:01:29',
               '2017-01-01 00:01:30', '2017-01-01 00:01:31',
               '2017-01-01 00:01:32', '2017-01-01 00:01:33',
               '2017-01-01 00:01:34', '2017-01-01 00:01:35',
               '2017-01-01 00:01:36', '2017-01-01 00:01:37',
               '2017-01-01 00:01:38', '2017-01-01 00:01:39'],
              dtype='datetime64[ns]', freq='S')

それをインデックスに持つSeriesを作ります。値は、0から500までのランダムな整数です。

1
2
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
ts
2017-01-01 00:00:00    410
2017-01-01 00:00:01    166
2017-01-01 00:00:02    232
2017-01-01 00:00:03    256
2017-01-01 00:00:04    413
2017-01-01 00:00:05    410
2017-01-01 00:00:06    412
                      ...
2017-01-01 00:01:33    133
2017-01-01 00:01:34    366
2017-01-01 00:01:35    134
2017-01-01 00:01:36     77
2017-01-01 00:01:37    377
2017-01-01 00:01:38     86
2017-01-01 00:01:39    439
Freq: S, Length: 100, dtype: int64

Series.resampleメソッドで頻度を5分毎に変換します。(全部で1分39秒までしかないので、1行にまとまってしまいます)

1
ts.resample('5Min').sum()
2017-01-01    25083
Freq: 5T, dtype: int64

頻度を5秒毎に変換します。

1
ts.resample('5s').sum()
2017-01-01 00:00:00    1477
2017-01-01 00:00:05    1657
2017-01-01 00:00:10    1299
2017-01-01 00:00:15    1242
2017-01-01 00:00:20    1451
2017-01-01 00:00:25    1359
2017-01-01 00:00:30    1250
                       ...
2017-01-01 00:01:05    1334
2017-01-01 00:01:10    1093
2017-01-01 00:01:15    1297
2017-01-01 00:01:20    1308
2017-01-01 00:01:25    1407
2017-01-01 00:01:30     773
2017-01-01 00:01:35    1113
Freq: 5S, Length: 20, dtype: int64

頻度を30秒毎に変換します。

1
ts.resample('30s').sum()
2017-01-01 00:00:00    8485
2017-01-01 00:00:30    7098
2017-01-01 00:01:00    7614
2017-01-01 00:01:30    1886
Freq: 30S, dtype: int64

頻度を1日毎に変換します。1行にまとまってしまうところは5分毎に変換した場合と同じですが、「Freq」(頻度)の表記が「D」になっています。

1
ts.resample('1d').sum()
2017-01-01    25083
Freq: D, dtype: int64

タイムゾーンの扱い方の例を示す為に、date_range関数を使って下記のようなDatetimeIndexを作ります。

1
2
rng = pd.date_range('3/6/2017 00:00', periods=5, freq='D')
rng
DatetimeIndex(['2017-03-06', '2017-03-07', '2017-03-08', '2017-03-09',
               '2017-03-10'],
              dtype='datetime64[ns]', freq='D')

それをインデックスに持つSeriesを作ります。

1
2
ts = pd.Series(np.random.randn(len(rng)), rng)
ts
2017-03-06    0.464000
2017-03-07    0.227371
2017-03-08   -0.496922
2017-03-09    0.306389
2017-03-10   -2.290613
Freq: D, dtype: float64

タイムゾーンをUTC(協定世界時)に変換します。

1
2
ts_utc = ts.tz_localize('UTC')
ts_utc
2017-03-06 00:00:00+00:00    0.464000
2017-03-07 00:00:00+00:00    0.227371
2017-03-08 00:00:00+00:00   -0.496922
2017-03-09 00:00:00+00:00    0.306389
2017-03-10 00:00:00+00:00   -2.290613
Freq: D, dtype: float64

タイムゾーンをUS/Eastern(アメリカ東部標準時)に変更します。

1
ts_utc.tz_convert('US/Eastern')
2017-03-05 19:00:00-05:00    0.464000
2017-03-06 19:00:00-05:00    0.227371
2017-03-07 19:00:00-05:00   -0.496922
2017-03-08 19:00:00-05:00    0.306389
2017-03-09 19:00:00-05:00   -2.290613
Freq: D, dtype: float64

タイムゾーンを日本に変更します。

1
ts_utc.tz_convert('Japan')
2017-03-06 09:00:00+09:00    0.464000
2017-03-07 09:00:00+09:00    0.227371
2017-03-08 09:00:00+09:00   -0.496922
2017-03-09 09:00:00+09:00    0.306389
2017-03-10 09:00:00+09:00   -2.290613
Freq: D, dtype: float64

時刻と期間(time span)の変換の例を示す為に、date_range関数を使って下記のようなDatetimeIndexを作ります。

1
2
rng = pd.date_range('1/1/2017', periods=5, freq='M')
rng
DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30',
               '2017-05-31'],
              dtype='datetime64[ns]', freq='M')

それをインデックスに持つSeriesを作ります。

1
2
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts
2017-01-31   -1.134623
2017-02-28   -1.561819
2017-03-31   -0.260838
2017-04-30    0.281957
2017-05-31    1.523962
Freq: M, dtype: float64

Series.to_periodメソッドで時刻を期間に変換します。

1
2
ps = ts.to_period()
ps
2017-01   -1.134623
2017-02   -1.561819
2017-03   -0.260838
2017-04    0.281957
2017-05    1.523962
Freq: M, dtype: float64

元のtsのインデックスはDatetimeIndexであるのに対し、

1
ts.index
DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30',
               '2017-05-31'],
              dtype='datetime64[ns]', freq='M')

psのインデックスはPeriodIndexです。

1
ps.index
PeriodIndex(['2017-01', '2017-02', '2017-03', '2017-04', '2017-05'], dtype='period[M]', freq='M')

Series.to_timestampメソッドで期間から時刻に戻ります。

1
ps.to_timestamp()
2017-01-01   -1.134623
2017-02-01   -1.561819
2017-03-01   -0.260838
2017-04-01    0.281957
2017-05-01    1.523962
Freq: MS, dtype: float64
1
ps.to_timestamp().index
DatetimeIndex(['2017-01-01', '2017-02-01', '2017-03-01', '2017-04-01',
               '2017-05-01'],
              dtype='datetime64[ns]', freq='MS')

時刻と期間の変換の、もう少し複雑な例を見てみます。下記の例では、「11月を年度末とした時の四半期(Q)」(期間)から、「その四半期の直後の月始めの9時」(時刻)に変換しています。

まず、period_range関数で1990年の第1四半期(第1Q)から2000年の第4四半期(第4Q)までのPeriodIndexを作ります。

1
2
prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV')
prng
PeriodIndex(['1990Q1', '1990Q2', '1990Q3', '1990Q4', '1991Q1', '1991Q2',
             '1991Q3', '1991Q4', '1992Q1', '1992Q2', '1992Q3', '1992Q4',
             '1993Q1', '1993Q2', '1993Q3', '1993Q4', '1994Q1', '1994Q2',
             '1994Q3', '1994Q4', '1995Q1', '1995Q2', '1995Q3', '1995Q4',
             '1996Q1', '1996Q2', '1996Q3', '1996Q4', '1997Q1', '1997Q2',
             '1997Q3', '1997Q4', '1998Q1', '1998Q2', '1998Q3', '1998Q4',
             '1999Q1', '1999Q2', '1999Q3', '1999Q4', '2000Q1', '2000Q2',
             '2000Q3', '2000Q4'],
            dtype='period[Q-NOV]', freq='Q-NOV')

それをインデックスに持つSeriesを作ります。

1
2
ts = pd.Series(np.random.randn(len(prng)), prng)
ts
1990Q1   -0.902937
1990Q2    0.068159
1990Q3   -0.057873
1990Q4   -0.368204
1991Q1   -1.144073
1991Q2    0.861209
1991Q3    0.800193
            ...
1999Q2   -0.928797
1999Q3   -0.308853
1999Q4   -0.681087
2000Q1    0.377953
2000Q2    0.493672
2000Q3   -2.461467
2000Q4   -1.553902
Freq: Q-NOV, Length: 44, dtype: float64

PeriodIndex.asfreqメソッドを組み合わせて、表示日時や頻度を変更します。(複雑なので、この後ひとつずつ分解して説明します)

1
(prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
PeriodIndex(['1990-03-01 09:00', '1990-06-01 09:00', '1990-09-01 09:00',
             '1990-12-01 09:00', '1991-03-01 09:00', '1991-06-01 09:00',
             '1991-09-01 09:00', '1991-12-01 09:00', '1992-03-01 09:00',
             '1992-06-01 09:00', '1992-09-01 09:00', '1992-12-01 09:00',
             '1993-03-01 09:00', '1993-06-01 09:00', '1993-09-01 09:00',
             '1993-12-01 09:00', '1994-03-01 09:00', '1994-06-01 09:00',
             '1994-09-01 09:00', '1994-12-01 09:00', '1995-03-01 09:00',
             '1995-06-01 09:00', '1995-09-01 09:00', '1995-12-01 09:00',
             '1996-03-01 09:00', '1996-06-01 09:00', '1996-09-01 09:00',
             '1996-12-01 09:00', '1997-03-01 09:00', '1997-06-01 09:00',
             '1997-09-01 09:00', '1997-12-01 09:00', '1998-03-01 09:00',
             '1998-06-01 09:00', '1998-09-01 09:00', '1998-12-01 09:00',
             '1999-03-01 09:00', '1999-06-01 09:00', '1999-09-01 09:00',
             '1999-12-01 09:00', '2000-03-01 09:00', '2000-06-01 09:00',
             '2000-09-01 09:00', '2000-12-01 09:00'],
            dtype='period[H]', freq='H')

まずPeriodIndex.asfreqメソッドで、頻度を月毎に、四半期(Q)の終了月に揃えます。

1
prng.asfreq('M', 'e')
PeriodIndex(['1990-02', '1990-05', '1990-08', '1990-11', '1991-02', '1991-05',
             '1991-08', '1991-11', '1992-02', '1992-05', '1992-08', '1992-11',
             '1993-02', '1993-05', '1993-08', '1993-11', '1994-02', '1994-05',
             '1994-08', '1994-11', '1995-02', '1995-05', '1995-08', '1995-11',
             '1996-02', '1996-05', '1996-08', '1996-11', '1997-02', '1997-05',
             '1997-08', '1997-11', '1998-02', '1998-05', '1998-08', '1998-11',
             '1999-02', '1999-05', '1999-08', '1999-11', '2000-02', '2000-05',
             '2000-08', '2000-11'],
            dtype='period[M]', freq='M')

そこに1を足すことで、月をひと月進めます。

1
prng.asfreq('M', 'e') + 1
PeriodIndex(['1990-03', '1990-06', '1990-09', '1990-12', '1991-03', '1991-06',
             '1991-09', '1991-12', '1992-03', '1992-06', '1992-09', '1992-12',
             '1993-03', '1993-06', '1993-09', '1993-12', '1994-03', '1994-06',
             '1994-09', '1994-12', '1995-03', '1995-06', '1995-09', '1995-12',
             '1996-03', '1996-06', '1996-09', '1996-12', '1997-03', '1997-06',
             '1997-09', '1997-12', '1998-03', '1998-06', '1998-09', '1998-12',
             '1999-03', '1999-06', '1999-09', '1999-12', '2000-03', '2000-06',
             '2000-09', '2000-12'],
            dtype='period[M]', freq='M')

更にPeriodIndex.asfreqメソッドで、頻度を時間毎にして、1日の0時に揃えます。

1
(prng.asfreq('M', 'e') + 1).asfreq('H', 's')
PeriodIndex(['1990-03-01 00:00', '1990-06-01 00:00', '1990-09-01 00:00',
             '1990-12-01 00:00', '1991-03-01 00:00', '1991-06-01 00:00',
             '1991-09-01 00:00', '1991-12-01 00:00', '1992-03-01 00:00',
             '1992-06-01 00:00', '1992-09-01 00:00', '1992-12-01 00:00',
             '1993-03-01 00:00', '1993-06-01 00:00', '1993-09-01 00:00',
             '1993-12-01 00:00', '1994-03-01 00:00', '1994-06-01 00:00',
             '1994-09-01 00:00', '1994-12-01 00:00', '1995-03-01 00:00',
             '1995-06-01 00:00', '1995-09-01 00:00', '1995-12-01 00:00',
             '1996-03-01 00:00', '1996-06-01 00:00', '1996-09-01 00:00',
             '1996-12-01 00:00', '1997-03-01 00:00', '1997-06-01 00:00',
             '1997-09-01 00:00', '1997-12-01 00:00', '1998-03-01 00:00',
             '1998-06-01 00:00', '1998-09-01 00:00', '1998-12-01 00:00',
             '1999-03-01 00:00', '1999-06-01 00:00', '1999-09-01 00:00',
             '1999-12-01 00:00', '2000-03-01 00:00', '2000-06-01 00:00',
             '2000-09-01 00:00', '2000-12-01 00:00'],
            dtype='period[H]', freq='H')

最後に9を足して、時間を9時に揃えます。

1
(prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
PeriodIndex(['1990-03-01 09:00', '1990-06-01 09:00', '1990-09-01 09:00',
             '1990-12-01 09:00', '1991-03-01 09:00', '1991-06-01 09:00',
             '1991-09-01 09:00', '1991-12-01 09:00', '1992-03-01 09:00',
             '1992-06-01 09:00', '1992-09-01 09:00', '1992-12-01 09:00',
             '1993-03-01 09:00', '1993-06-01 09:00', '1993-09-01 09:00',
             '1993-12-01 09:00', '1994-03-01 09:00', '1994-06-01 09:00',
             '1994-09-01 09:00', '1994-12-01 09:00', '1995-03-01 09:00',
             '1995-06-01 09:00', '1995-09-01 09:00', '1995-12-01 09:00',
             '1996-03-01 09:00', '1996-06-01 09:00', '1996-09-01 09:00',
             '1996-12-01 09:00', '1997-03-01 09:00', '1997-06-01 09:00',
             '1997-09-01 09:00', '1997-12-01 09:00', '1998-03-01 09:00',
             '1998-06-01 09:00', '1998-09-01 09:00', '1998-12-01 09:00',
             '1999-03-01 09:00', '1999-06-01 09:00', '1999-09-01 09:00',
             '1999-12-01 09:00', '2000-03-01 09:00', '2000-06-01 09:00',
             '2000-09-01 09:00', '2000-12-01 09:00'],
            dtype='period[H]', freq='H')

これをtsのインデックスにセットすると、こうなります。

1
2
ts.index = (prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9
ts.head()
1990-03-01 09:00   -0.902937
1990-06-01 09:00    0.068159
1990-09-01 09:00   -0.057873
1990-12-01 09:00   -0.368204
1991-03-01 09:00   -1.144073
Freq: H, dtype: float64

13.   カテゴリ型[17]

pandasでは、DataFrameにカテゴリ型のデータを含めることができます。

例を示す為にまずは下記のようなDataFrameを用意します。AからEの成績データを、そのまま文字列で表現しています。

1
2
df = pd.DataFrame({'id':[1,2,3,4,5,6], 'raw_grade':['a', 'b', 'b', 'a', 'a', 'e']})
df
id raw_grade
0 1 a
1 2 b
2 3 b
3 4 a
4 5 a
5 6 e

「raw_grade」カラム(列)の成績をSeries.astypeメソッドでカテゴリ型に変換して、「grade」カラム(列)に格納します。[24]dtypeが「category」になっていることが分かります。

1
2
df['grade'] = df['raw_grade'].astype('category')
df['grade']
0    a
1    b
2    b
3    a
4    a
5    e
Name: grade, dtype: category
Categories (3, object): [a, b, e]

DataFrame全体を確認します。

1
df
id raw_grade grade
0 1 a a
1 2 b b
2 3 b b
3 4 a a
4 5 a a
5 6 e e

Series.cat.categoriesプロパティでカテゴリの値を取得したり、セットしたりできます。

1
df['grade'].cat.categories
Index(['a', 'b', 'e'], dtype='object')

ここでは、それぞれA、B、Eをもっと分かり易く「very good」「good」「very bad」に変更します。

1
2
df['grade'].cat.categories = ['very good', 'good', 'very bad']
df['grade'].cat.categories
Index(['very good', 'good', 'very bad'], dtype='object')

「grade」カラム(列)を確認します。

1
df['grade']
0    very good
1         good
2         good
3    very good
4    very good
5     very bad
Name: grade, dtype: category
Categories (3, object): [very good, good, very bad]

Series.cat.set_categoriesメソッドを使えば、そのSeriesに存在しない値も含めてカテゴリを再設定できます。

1
df['grade'].cat.set_categories(['very bad', 'bad', 'medium', 'good', 'very good'])
0    very good
1         good
2         good
3    very good
4    very good
5     very bad
Name: grade, dtype: category
Categories (5, object): [very bad, bad, medium, good, very good]

Series.cat.set_categoriesは、初期設定では新しいSeriesを返すので、「grade」カラム(列)を置き換える場合は、例えば下記のように代入し直します。

1
2
df['grade'] = df['grade'].cat.set_categories(['very bad', 'bad', 'medium', 'good', 'very good'])
df['grade']
0    very good
1         good
2         good
3    very good
4    very good
5     very bad
Name: grade, dtype: category
Categories (5, object): [very bad, bad, medium, good, very good]

この時点のDataFrameを確認します。

1
df
id raw_grade grade
0 1 a very good
1 2 b good
2 3 b good
3 4 a very good
4 5 a very good
5 6 e very bad

カテゴリ型データをDataFrame.sort_valuesメソッドで並び替えると、文字の順序ではなく、カテゴリの順序で並び替えられます。

1
df.sort_values(by='grade')
id raw_grade grade
5 6 e very bad
1 2 b good
2 3 b good
0 1 a very good
3 4 a very good
4 5 a very good

DataFrame.groupbyでグループ化した場合は、空のグループも表示してくれます。

1
df.groupby('grade').size()
grade
very bad     1
bad          0
medium       0
good         2
very good    3
dtype: int64

Series.value_countsでも、0個の要素を表示してくれます。

1
df['grade'].value_counts()
very good    3
good         2
very bad     1
medium       0
bad          0
Name: grade, dtype: int64

14.   プロット[18]

データをグラフとしてプロットするには、Series.plotメソッドやDataFrame.plotメソッドを使います。

例を示す為に、2000/1/1から1000日分のインデックスとランダムな値を持ったSeriesを作ります。

1
2
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts
2000-01-01    2.015523
2000-01-02   -1.833722
2000-01-03    1.771740
2000-01-04   -0.670027
2000-01-05    0.049307
2000-01-06   -0.521493
2000-01-07   -3.201750
                ...
2002-09-20   -1.187785
2002-09-21   -0.183798
2002-09-22   -1.211230
2002-09-23   -0.856833
2002-09-24   -0.600575
2002-09-25    0.361428
2002-09-26    0.887304
Freq: D, Length: 1000, dtype: float64

Series.cumsumメソッドで累積和を計算して、置き換えます。

1
2
ts = ts.cumsum()
ts
2000-01-01     2.015523
2000-01-02     0.181801
2000-01-03     1.953541
2000-01-04     1.283514
2000-01-05     1.332821
2000-01-06     0.811328
2000-01-07    -2.390423
                ...
2002-09-20   -12.233834
2002-09-21   -12.417632
2002-09-22   -13.628862
2002-09-23   -14.485695
2002-09-24   -15.086270
2002-09-25   -14.724842
2002-09-26   -13.837538
Freq: D, Length: 1000, dtype: float64

Series.plotメソッドでグラフを描画します。グラフ描画にはmatplotlibが使用されます。グラフがどこに表示されるかは、環境・設定によります。

1
ts.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x10dea2048>
plot 01

DataFrameの場合の例も示します。例を示す為に、先ほどのSeriesをインデックスに持ち、A、B、C、Dの4つのカラム(列)を持ったDataFrameを作成します。

1
2
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=['A', 'B', 'C', 'D'])
df
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.437189 0.053768 1.872644 -1.469813
2000-01-03 -0.564201 0.876341 0.407749 -0.232583
2000-01-04 0.179812 0.922152 -1.820952 -0.641360
2000-01-05 2.133239 -0.941248 -0.136307 -1.271305
2000-01-06 -0.099774 -0.061438 -0.845172 0.465793
2000-01-07 0.756995 -0.541690 -0.802241 0.877657
... ... ... ... ...
2002-09-20 1.279409 -0.395335 -0.451316 0.839783
2002-09-21 0.238172 0.426073 1.483501 2.600168
2002-09-22 1.405015 0.241867 1.730183 0.453633
2002-09-23 -0.573198 -0.295592 0.169647 -0.849301
2002-09-24 -0.343498 -0.559274 0.113176 -0.412847
2002-09-25 -0.313962 -0.140192 0.452837 -0.347033
2002-09-26 -1.640754 -1.190330 0.717777 -0.389192

1000 rows × 4 columns

DataFrame.cumsumメソッドで累積和を計算して、置き換えます。

1
2
df = df.cumsum()
df
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2000-01-03 -1.734933 0.530468 2.060811 -0.515536
2000-01-04 -1.555121 1.452620 0.239859 -1.156896
2000-01-05 0.578117 0.511371 0.103552 -2.428202
2000-01-06 0.478344 0.449933 -0.741620 -1.962409
2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ...
2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 4 columns

matplotlib.pyplot.figureメソッドで、新規Figureオブジェクトを作成し(matplotlibの使い方の詳細はここでは割愛します)、DataFrame.plotメソッドでグラフを描画します。

また、matplotlib.pyplot.legendメソッドで、凡例を表示することを明示的に支持しています。

1
2
3
plt.figure()
df.plot()
plt.legend(loc='best')
<matplotlib.legend.Legend at 0x110c36278>
<matplotlib.figure.Figure at 0x110c9cf60>
plot 02

Figureの作成や凡例表示の指示は、省略可能です。

1
df.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x110e97a58>
plot 02

15.   データ入出力

各種形式のデータからDataFrameを生成したり、DataFrameから各種形式のデータを作成する方法について紹介します。

15.1.   CSV[24]

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2000-01-03 -1.734933 0.530468 2.060811 -0.515536
2000-01-04 -1.555121 1.452620 0.239859 -1.156896
2000-01-05 0.578117 0.511371 0.103552 -2.428202
2000-01-06 0.478344 0.449933 -0.741620 -1.962409
2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ...
2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 4 columns

15.1.1.   出力[19]

DataFrame.to_csvメソッドを使います。

1
df.to_csv('foo.csv')

15.1.2.   入力[20][25][27][26]

read_csv関数を使います。

1
pd.read_csv('foo.csv')
Unnamed: 0 A B C D
0 2000-01-01 0.266457 -0.399641 -0.219582 1.186860
1 2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2 2000-01-03 -1.734933 0.530468 2.060811 -0.515536
3 2000-01-04 -1.555121 1.452620 0.239859 -1.156896
4 2000-01-05 0.578117 0.511371 0.103552 -2.428202
5 2000-01-06 0.478344 0.449933 -0.741620 -1.962409
6 2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ... ...
993 2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
994 2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
995 2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
996 2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
997 2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
998 2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
999 2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 5 columns

15.2.   HDF5[21]

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2000-01-03 -1.734933 0.530468 2.060811 -0.515536
2000-01-04 -1.555121 1.452620 0.239859 -1.156896
2000-01-05 0.578117 0.511371 0.103552 -2.428202
2000-01-06 0.478344 0.449933 -0.741620 -1.962409
2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ...
2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 4 columns

15.2.1.   出力

DataFrame.to_hdfメソッドを使います。

1
df.to_hdf('foo.h5', 'df')

15.2.2.   入力

read_hdf関数を使います。

1
pd.read_hdf('foo.h5', 'df')
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2000-01-03 -1.734933 0.530468 2.060811 -0.515536
2000-01-04 -1.555121 1.452620 0.239859 -1.156896
2000-01-05 0.578117 0.511371 0.103552 -2.428202
2000-01-06 0.478344 0.449933 -0.741620 -1.962409
2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ...
2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 4 columns

15.3.   Excel[22]

処理を理解し易いように、まずは元のDataFrameを確認しておきます。

1
df
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2000-01-03 -1.734933 0.530468 2.060811 -0.515536
2000-01-04 -1.555121 1.452620 0.239859 -1.156896
2000-01-05 0.578117 0.511371 0.103552 -2.428202
2000-01-06 0.478344 0.449933 -0.741620 -1.962409
2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ...
2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 4 columns

15.3.1.   出力

DataFrame.to_excelメソッドを使います。

1
df.to_excel('foo.xlsx', sheet_name='Sheet1')

15.3.2.   入力

read_excel関数を使います。

1
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
A B C D
2000-01-01 0.266457 -0.399641 -0.219582 1.186860
2000-01-02 -1.170732 -0.345873 1.653061 -0.282953
2000-01-03 -1.734933 0.530468 2.060811 -0.515536
2000-01-04 -1.555121 1.452620 0.239859 -1.156896
2000-01-05 0.578117 0.511371 0.103552 -2.428202
2000-01-06 0.478344 0.449933 -0.741620 -1.962409
2000-01-07 1.235339 -0.091757 -1.543861 -1.084753
... ... ... ... ...
2002-09-20 -10.628548 -9.153563 -7.883146 28.313940
2002-09-21 -10.390377 -8.727491 -6.399645 30.914107
2002-09-22 -8.985362 -8.485624 -4.669462 31.367740
2002-09-23 -9.558560 -8.781216 -4.499815 30.518439
2002-09-24 -9.902058 -9.340490 -4.386639 30.105593
2002-09-25 -10.216020 -9.480682 -3.933802 29.758560
2002-09-26 -11.856774 -10.671012 -3.216025 29.369368

1000 rows × 4 columns

16.   参考リンク

16.2.   その他

以下の各記事の対象Ver.は、記事中に明記されているもの以外は、記事の更新日時で判断しています。

16.2.1.   pandas 0.19.2以前を対象とした記事

[23](1, 2, 3, 4, 5, 6, 7, 8, 9) pandasの基本操作 - Qiita

16.2.2.   pandas 0.18.1を対象とした記事

[24](1, 2, 3, 4, 5, 6, 7, 8) [Python] pandasの使い方まとめ - Qiita
[25](1, 2, 3, 4) Pandas の DataFrame の基本的な使い方 - akiyoko blog

16.2.3.   pandas 0.17.1以前を対象とした記事

[26](1, 2) Pythonでpandasを使う - 計算物理屋の研究備忘録 (pandas 0.20.1から非推奨になった.ixが使われていることに注意)

16.2.4.   pandas 0.16.2以前を対象とした記事

[27](1, 2, 3) データ分析ライブラリPandasの使い方 - Librabuch (pandas 0.17.0から廃止になったsort()が使われていることに注意)