Python で解析 11

“Advent Calendar 2013 - Python で解析!” の十一日目。DataFrame - 7

1. 前回の補足

今回は concat を取り上げるのだが、その前に、十日目の記事を読み返していたら、書き忘れていたことがあったので、先に補足しておく。

In [10]: df4 = df1.join([df2, df3])

In [11]: df4
Out[11]:
       体重  名前 性別   身長         誕生日 好きなもの
3B005  79  山田  男  181  1982/02/02   ばなな
3B003  71  鈴木  男  173  1983/03/03   いちご
3B002  51  佐藤  女  159  1984/04/04   NaN
3B001  52  木村  女  164         NaN   メロン

上の join の場合、'how' に 'left' を指定したのと同じになる。

In [12]: df1.join([df2, df3], how='left')
Out[12]:
       体重  名前 性別   身長         誕生日 好きなもの
3B005  79  山田  男  181  1982/02/02   ばなな
3B003  71  鈴木  男  173  1983/03/03   いちご
3B002  51  佐藤  女  159  1984/04/04   NaN
3B001  52  木村  女  164         NaN   メロン

merge の場合の省略値は 'inner' だったが、join でも 'inner' を指定することができる。

In [13]: df1.join([df2, df3], how='inner')
Out[13]:
       体重  名前 性別   身長         誕生日 好きなもの
3B005  79  山田  男  181  1982/02/02   ばなな
3B003  71  鈴木  男  173  1983/03/03   いちご

'outer' も指定できる。

In [14]: df1.join([df2, df3], how='outer')
Out[14]:
       体重   名前   性別   身長         誕生日 好きなもの
3B001  52   木村    女  164         NaN   メロン
3B002  51   佐藤    女  159  1984/04/04   NaN
3B003  71   鈴木    男  173  1983/03/03   いちご
3B004 NaN  NaN  NaN  NaN  1981/01/01   りんご
3B005  79   山田    男  181  1982/02/02   ばなな

だが、 join で複数の DataFrame をつなぐ時には 'right' は指定できない。

In [15]: df1.join([df2, df3], how='right')
(中略)
ValueError: Only can inner (intersect) or outer (union) join the other axis

一つだけなら OK。

In [16]: df1.join(df2, how='right')
Out[16]:
       体重   名前   性別   身長         誕生日
3B004 NaN  NaN  NaN  NaN  1981/01/01
3B005  79   山田    男  181  1982/02/02
3B003  71   鈴木    男  173  1983/03/03
3B002  51   佐藤    女  159  1984/04/04

2. では、 concat のための準備を

In [1]: import pandas as pd

In [2]: df1 = pd.DataFrame({
   ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...: u'性別': [u'男', u'男', u'女', u'女'] ,
   ...: u'身長': [181, 173, 159, 164],
   ...: u'体重': [79, 71, 51, 52]
   ...: },
   ...: index=['3B005', '3B003', '3B002', '3B001']
   ...: )

In [3]: df2 = pd.DataFrame({
   ...: u'名前': [u'田中', u'山田', u'鈴木', u'佐藤'],
   ...: u'誕生日': ['1981/01/01', '1982/02/02', '1983/03/03', '1984/04/04']
   ...: },
   ...: index=['3B004','3B005','3B003', '3B002']
   ...: )

In [4]: df1
Out[4]:
       体重  名前 性別   身長
3B005  79  山田  男  181
3B003  71  鈴木  男  173
3B002  51  佐藤  女  159
3B001  52  木村  女  164

In [5]: df2
Out[5]:
       名前         誕生日
3B004  田中  1981/01/01
3B005  山田  1982/02/02
3B003  鈴木  1983/03/03
3B002  佐藤  1984/04/04

3. で、 concat を

merge や join は横につなぐイメージ (結合) だが、 concat は縦につなぐイメージ (連結)。通常の python の list + list のようなものだ。

In [6]: df3 = pd.concat([df1, df2])

In [7]: df3
Out[7]:
       体重  名前   性別         誕生日   身長
3B005  79  山田    男         NaN  181
3B003  71  鈴木    男         NaN  173
3B002  51  佐藤    女         NaN  159
3B001  52  木村    女         NaN  164
3B004 NaN  田中  NaN  1981/01/01  NaN
3B005 NaN  山田  NaN  1982/02/02  NaN
3B003 NaN  鈴木  NaN  1983/03/03  NaN
3B002 NaN  佐藤  NaN  1984/04/04  NaN

レコードは単純に追加されるので、index が同じでも関係がなく、別のレコードして追加される。同じ名前のカラムは統合され、そうでないものは追加される。

In [8]: df3.columns
Out[8]: Index([u'体重', u'名前', u'性別', u'誕生日', u'身長'], dtype=object)

In [9]: df3.index
Out[9]: Index([u'3B005', u'3B003', u'3B002', u'3B001', u'3B004', u'3B005', u'3B003', u'3B002'], dtype=object)

連結後は index が一意になってないことに注意。DataFrame の index は RDBMS のようにユニーク制約という訳ではないようだ。その代わりに (?)、ユニークかどうかをチェックすることができる。

In [10]: df3.index.is_unique
Out[10]: False

今回はこんなところで。

Python で解析 10

“Advent Calendar 2013 - Python で解析!” の十日目。DataFrame - 6

1. お決まりの準備を…

今回は DataFrame の join について。 join は merge のお手軽版といったところのようだ。インデックスがあって、カラムが重複していない場合には、merge よりもお手軽なので、使いやすいと思われる。という訳で、準備を。

In [1]: import pandas as pd

In [2]: df1 = pd.DataFrame({
   ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...: u'性別': [u'男', u'男', u'女', u'女'] ,
   ...: u'身長': [181, 173, 159, 164],
   ...: u'体重': [79, 71, 51, 52]
   ...: },
   ...: index=['3B005', '3B003', '3B002', '3B001']
   ...: )

In [3]: df2 = pd.DataFrame({
   ...: u'誕生日': ['1981/01/01', '1982/02/02', '1983/03/03', '1984/04/04']
   ...: },
   ...: index=['3B004','3B005','3B003', '3B002']
   ...: )

In [4]: df3 = pd.DataFrame({
   ...: u'好きなもの': [u'りんご', u'ばなな', u'いちご', u'メロン'],
   ...: },
   ...: index=['3B004','3B005','3B003', '3B001']
   ...: )

In [5]: df1
Out[5]:
       体重  名前 性別   身長
3B005  79  山田  男  181
3B003  71  鈴木  男  173
3B002  51  佐藤  女  159
3B001  52  木村  女  164

In [6]: df2
Out[6]:
              誕生日
3B004  1981/01/01
3B005  1982/02/02
3B003  1983/03/03
3B002  1984/04/04

In [7]: df3
Out[7]:
      好きなもの
3B004   りんご
3B005   ばなな
3B003   いちご
3B001   メロン

今回は DataFrame が三つある。そして、それぞれのカラムが別々で、名前や性別は df1 にしかない。その代わりに index が付けてある。 index は初めて登場するが、RDBMS でいうところのプライマリーキーのようなものだ。そして、プリフィックスとして '3B' が付いているのは "三年 B 組、金八先生!" を思い出して付けてみただけ。深い意味はない。

2. 早速 join

論より証拠ということで join してみる。

In [8]: df1.join(df2)
Out[8]:
       体重  名前 性別   身長         誕生日
3B005  79  山田  男  181  1982/02/02
3B003  71  鈴木  男  173  1983/03/03
3B002  51  佐藤  女  159  1984/04/04
3B001  52  木村  女  164         NaN

逆にするとこうなる。

In [9]: df2.join(df1)
Out[9]:
              誕生日  体重   名前   性別   身長
3B004  1981/01/01 NaN  NaN  NaN  NaN
3B005  1982/02/02  79   山田    男  181
3B003  1983/03/03  71   鈴木    男  173
3B002  1984/04/04  51   佐藤    女  159

3. 複数の join

たぶん、 join の真骨頂はこれ。

In [10]: df4 = df1.join([df2, df3])

In [11]: df4
Out[11]:
       体重  名前 性別   身長         誕生日 好きなもの
3B005  79  山田  男  181  1982/02/02   ばなな
3B003  71  鈴木  男  173  1983/03/03   いちご
3B002  51  佐藤  女  159  1984/04/04   NaN
3B001  52  木村  女  164         NaN   メロン

インデックスさえ一致していれば (& 重複カラムがなければ)、複数の DataFrame を簡単に統合できてしまう。これに慣れてしまうと、SQL が面倒になってしまうのが弊害か…。

4. おまけ

カラムやインデックスを確認する方法は次の通り。

In [12]: df4.columns
Out[12]: Index([u'体重', u'名前', u'性別', u'身長', u'誕生日', u'好きなもの'], dtype=object)

In [13]: df4.index
Out[13]: Index([u'3B005', u'3B003', u'3B002', u'3B001'], dtype=object)

付け替えることもできる。

In [14]: df4.columns = ['weight', 'name', 'sex', 'height', 'birthday', 'favorite food']

In [15]: df4.columns
Out[15]: Index([u'weight', u'name', u'sex', u'height', u'birthday', u'favorite food'], dtype=object)

以後、新しいカラム名を使って操作することになる。

In [16]: df4[u'weight']
Out[16]:
3B005    79
3B003    71
3B002    51
3B001    52
Name: weight, dtype: int64

今回はこんなところで。

Python で解析 9

“Advent Calendar 2013 - Python で解析!” の九日目。DataFrame - 6

1. お決まりの準備を…

今回は DataFrame のマージについて。マージとは、二つのデータフレームを結合することで、SQL で言うところの join と同等のもので、数学的には集合演算とかベン図とか…を思い出してもらえればいいだろう。さて、その前にいつものように準備を。

In [1]: import pandas as pd

In [2]: df1 = pd.DataFrame({
   ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...: u'性別': [u'男', u'男', u'女', u'女'] ,
   ...: u'身長': [181, 173, 159, 164],
   ...: u'体重': [79, 71, 51, 52]
   ...: })

In [3]: df2 = pd.DataFrame({
   ...: u'名前': [u'田中', u'山田', u'鈴木', u'佐藤'],
   ...: u'性別': [u'男', u'女', u'男', u'女'] ,
   ...: u'誕生日': ['1981/01/01', '1982/02/02', '1983/03/03', '1984/04/04']
   ...: })

In [4]: df1
Out[4]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173
2  51  佐藤  女  159
3  52  木村  女  164

In [5]: df2
Out[5]:
   名前 性別         誕生日
0  田中  男  1981/01/01
1  山田  女  1982/02/02
2  鈴木  男  1983/03/03
3  佐藤  女  1984/04/04

今回はマージを取り扱うので、データは二つ用意する。誕生日のデータの方には、田中くんが増えていて、山田さんが女性になっていて、木村さんがいないという違いがある。そして、データの順番が一致していない。マージの振る舞いを確認するために、わざと少しばかりややこしくしている。

1. 何も考えずにマージ

In [6]: pd.merge(df1, df2)
Out[6]:
   体重  名前 性別   身長         誕生日
0  71  鈴木  男  173  1983/03/03
1  51  佐藤  女  159  1984/04/04

件数が少なくなってしまったが、表示されている各数値に間違いはないので、どうやらマージはできたようだ。

2. キーカラムを指定してマージ

Pandas の merge は、指定したそれぞれの DataFrame の同じカラム名をキーにしてマージする。なので、実は次のようにカラム名を指定したのと同じことなのだ。

In [7]: pd.merge(df1, df2, on=[u'名前', u'性別'])
Out[7]:
   体重  名前 性別   身長         誕生日
0  71  鈴木  男  173  1983/03/03
1  51  佐藤  女  159  1984/04/04

SQL もこのぐらい便宜を計らってほしいものだが…というのはさておき…。

試しに性別がキーに含まれないようにして、名前だけでマージすると次のようになる。

In [8]: pd.merge(df1, df2, on=u'名前')
Out[8]:
   体重  名前 性別_x   身長 性別_y         誕生日
0  79  山田    男  1811982/02/02
1  71  鈴木    男  1731983/03/03
2  51  佐藤    女  1591984/04/04

性別が一致しなくても、名前だけで一致すればいいので、山田氏のレコードが増えた。その一方で、性別項目が二つできている。性別のサフィックスの '_x' が左に書いた df1 のもので、'_y' が右に書いた df2 のもの。

3. レコード数の差異を制御

df1 と df2 が完全に一致してないので、それをどう取り扱うかを制御してみる。SQL で言うところの left join とか outer join とか…のことだ。

最初の例では 2 件になってしまったが、それは両方に存在するレコードのみが抽出されたからで、以下と同等。

In [9]: pd.merge(df1, df2, how='inner')
Out[9]:
   体重  名前 性別   身長         誕生日
0  71  鈴木  男  173  1983/03/03
1  51  佐藤  女  159  1984/04/04

左側 (すなわち df1) さえあれば、右側 (すなわち df2) がなくてもかまわないなら、次のように書く。

In [10]: pd.merge(df1, df2, how='left')
Out[10]:
   体重  名前 性別   身長         誕生日
0  79  山田  男  181         NaN
1  71  鈴木  男  173  1983/03/03
2  51  佐藤  女  159  1984/04/04
3  52  木村  女  164         NaN

逆に左側がなくても、右側さえあれば良いなら、次のように書く。

In [11]: pd.merge(df1, df2, how='right')
Out[11]:
   体重  名前 性別   身長         誕生日
0  71  鈴木  男  173  1983/03/03
1  51  佐藤  女  159  1984/04/04
2 NaN  田中  男  NaN  1981/01/01
3 NaN  山田  女  NaN  1982/02/02

どちらか片方にさえあれば有効とするなら、how に 'outer' を指定する。

In [12]: pd.merge(df1, df2, how='outer')
Out[12]:
   体重  名前 性別   身長         誕生日
0  79  山田  男  181         NaN
1  71  鈴木  男  173  1983/03/03
2  51  佐藤  女  159  1984/04/04
3  52  木村  女  164         NaN
4 NaN  田中  男  NaN  1981/01/01
5 NaN  山田  女  NaN  1982/02/02

これが最大件数になる。

いずれの例でも同じく、データが存在しないところは NaN (Not a Number) となる。

なお、ここまでの例で 'pd.mege()' としているが、'df1.merge(df2)' のように書くことともできる。今回の説明の on や how の意味も同じように使える。'df1.merge(df2)' の方がオブジェクト指向らしい書き方なのだが、軽く調べた限りではマイノリティーな感じ。データマイニングする人は、オブジェクト指向にこだわらない傾向があるのかもしれない。

今回はこんなところで。

Python で解析 8

“Advent Calendar 2013 - Python で解析!” の八日目。DataFrame - 5

1. お決まりの準備を…

今回は DataFrame の保存だが、その前に例によって準備を。

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({
   ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...: u'性別': [u'男', u'男', u'女', u'女'] ,
   ...: u'身長': [181, 173, 159, 164],
   ...: u'体重': [79, 71, 51, 52]
   ...: })

In [3]: df
Out[3]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173
2  51  佐藤  女  159
3  52  木村  女  164

2. バイナリ形式のセーブ

DataFrame はそのまま保存できる。

df.save('hoge.pickle')

…が、save すると "save is deprecated, use to_pickle" と警告が表示されるので、to_pickle の方を使うようにする。

df.to_pickle('hoge.pickle')

保存したファイルを読み込む場合は read_pickle を使う。

In [5]: df2 = pd.read_pickle('hoge.pickle')

In [6]: df2
Out[6]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173
2  51  佐藤  女  159
3  52  木村  女  164

再現できた。

3. テキスト形式のセーブ

to_csv でテキスト形式で保存できる。

df.to_csv('hoge.csv')

日本語を含む場合は、encoding を指定する。

In [9]: df.to_csv('hoge.csv', encoding='utf-8')

In [10]: !cat hoge.csv
,体重,名前,性別,身長
0,79,山田,男,181
1,71,鈴木,男,173
2,51,佐藤,女,159
3,52,木村,女,164

タブ区切りなら、sep を指定する。

In [11]: df.to_csv('hoge.tsv', encoding='utf-8', sep='\t')

In [12]: In [10]: !cat hoge.tsv
	体重	名前	性別	身長
0	79	山田	男	181
1	71	鈴木	男	173
2	51	佐藤	女	159
3	52	木村	女	164

4. Excel 形式ののセーブ

Excel 形式でも保存できるが、そのためには xlwt をインストールしておく必要がある。

$ pip install xlwt

テキスト形式の保存より、少し手間がかかるが、次のような手順で Excel 形式で保存できる。

In [13]: xl = pd.ExcelWriter('hoge.xls')

In [14]: df.to_excel(xl, 'Sheet1')

In [15]: xl.save()

In [16]: !ls -l hoge.xls
-rw-r--r--  1 tokutomi  staff  5632 12  8 09:27 hoge.xls

pythonista ならこう書きたいところだが…。

with(pd.ExcelWriter('hoge.xls')) as xl:
  df.to_excel(xl, 'Sheet1')

"AttributeError: __exit__" とのことで、with には対応してないようだ。残念…。

そういえば、さらっと '!cat' や '!ls' のようにシェルコマンドを書いているが、 ipython から抜けずにシェルコマンドを使えて便利である。実は先頭の '!' を付けずに 'ls' とだけしても使えるのだが、同じ変数名があったりなどすると、そちらが優先されるので、 '!' を付けて実行する方が確実だろう。

今回は、こんなところで。

Python で解析 7

“Advent Calendar 2013 - Python で解析!” の七日目。matplotlib - 2

1. 準備

Notebook を使いたいところだが、ブログにコードを書くのにスクリーンショットでは都合が悪いので、ターミナルの ipython を使う。起動時に '--pylab=inline' を付けておくと、'show()' を実行しなくてもチャートが表示されて便利。

$ ipython --pylab=inline

今回は pylab もインポートしておく。

In [1]: import pandas as pd

In [2]: import pylab as pl

In [3]: import pandas as pd

In [4]: df = pd.DataFrame({
   ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...: u'性別': [u'男', u'男', u'女', u'女'] ,
   ...: u'身長': [181, 173, 159, 164],
   ...: u'体重': [79, 71, 51, 52]
   ...: })

In [5]: df
Out[5]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173
2  51  佐藤  女  159
3  52  木村  女  164

2. 散布図

データを手に入れたら 'とりあえず散布図' ということで。

In [6]: pl.scatter(df[u'身長'], df[u'体重'])
Out[6]: <matplotlib.collections.PathCollection at 0x1077a2e90>

この散布図は Pandas でなくても matplotlib に配列を渡して表示できる。

なお、ipython の起動時に pylab を読み込んでいるので、'pl.scatter()' ではなく 'scatter()' として使うこともできるのだが、後々のことを考えて、どのモジュールの機能を使うのかが明らかである 'pl.scatter()' という書き方を選んでいる。

3. 散布図マトリックス

Pandas だとこれが便利。

In [7]: pd.scatter_matrix(df)
Out[7]:
array([[<matplotlib.axes.AxesSubplot object at 0x1077b9f50>,
        <matplotlib.axes.AxesSubplot object at 0x1078d28d0>],
       [<matplotlib.axes.AxesSubplot object at 0x1078f64d0>,
        <matplotlib.axes.AxesSubplot object at 0x1077c9310>]], dtype=object)


今回はこんなところで。

Python で解析 6

“Advent Calendar 2013 - Python で解析!” の六日目。Pandas で DataFrame - 4

1. お決まりの準備を…

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({
   ...: u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...: u'性別': [u'男', u'男', u'女', u'女'] ,
   ...: u'身長': [181, 173, 159, 164],
   ...: u'体重': [79, 71, 51, 52]
   ...: })

In [3]: df
Out[3]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173
2  51  佐藤  女  159
3  52  木村  女  164

2. Series と DataFrame

ここまで便利に DataFrame を使ってきたが、念のために確認しておく。

In [4]: type(df)
Out[4]: pandas.core.frame.DataFrame

DataFrame の列も確認してみる。

In [5]: type(df[u'名前'])
Out[5]: pandas.core.series.Series

Series が返って来るようだ。DataFrame も Series も Pandas で定義されていて、 Series は一次元のデータを取り扱う。

In [6]: type(df.iloc[1])
Out[6]: pandas.core.series.Series

行を取り出しても Series になっている。

これまで DataFrame の関数を呼び出していたが、実は Series にも使える。

In [7]: df[u'体重'].sum()
Out[7]: 253

In [8]: df[u'体重'].describe()
Out[8]:
count     4.000000
mean     63.250000
std      13.961256
min      51.000000
25%      51.750000
50%      61.500000
75%      73.000000
max      79.000000
dtype: float64

どうやら、 DataFrame の同等の関数は、各 Series の関数を呼び出して、その結果を表示していたようだ。

3. 条件に合致した行を選択…の補足

前回、条件に合致した行の選択方法を書いた。

In [9]: df.loc[df[u'身長']>170]
Out[9]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173

試しに、この条件文だけを実行してみる。

In [10]: df[u'身長']>170
Out[10]:
0     True
1     True
2    False
3    False
Name: 身長, dtype: bool

In [11]: type(df[u'身長']>170)
Out[11]: pandas.core.series.Series

bool の Series が戻ってくる。どうやら条件を渡して行を選択しているというよりも、 bool の配列を使ってマスクして行を抽出しているようだ。試しに、条件文の代わりに bool の配列を渡してみると、こうなる。

In [12]: df.loc[[True, True, False, False]]
Out[12]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173


ただし、この配列は行数に一致していなければならない。試してみると、エラーが表示される。

In [13]: df.loc[[True, True, False, False, True]]
Out[13]:
# (中略)
KeyError: Exception('Indices must be nonzero and less than the axis length',)

今回は、こんなところで。

Python で解析 5

“Advent Calendar 2013 - Python で解析!” の五日目。Pandas で DataFrame - 3

1. 例のごとく準備を…。

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({
   ...:     u'名前': [u'山田', u'鈴木', u'佐藤', u'木村'],
   ...:     u'性別': [u'男', u'男', u'女', u'女'] ,
   ...:     u'身長': [181, 173, 159, 164],
   ...:     u'体重': [79, 71, 51, 52]
   ...: })

In [3]: df
Out[3]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173
2  51  佐藤  女  159
3  52  木村  女  164 

2. 任意の行を選択

まずは、特定の行を取り出す。R は 1 から始まるが、Pandas では 0 から始まるという微妙な差がある。

In [4]: df.iloc[2]
Out[4]:
体重     51
名前     佐藤
性別      女
身長    159
Name: 2, dtype: object

配列を渡して、任意の複数行を取り出すこともできる。

In [5]: df.iloc[[3,1]]
Out[5]:
   体重  名前 性別   身長
3  52  木村  女  164
1  71  鈴木  男  173 

範囲指定で取り出すことも可能。R では "以上:以下" で指定するが、 Pandas では "以上:未満" で指定する。

In [6]: df.iloc[1:3]
Out[6]:
   体重  名前 性別   身長
1  71  鈴木  男  173
2  51  佐藤  女  159 

3. 条件に合致した行を選択

In [7]: df.loc[df[u'身長']>170]
Out[7]:
   体重  名前 性別   身長
0  79  山田  男  181
1  71  鈴木  男  173 
In [8]: df.loc[df[u'性別']==u'女']
Out[8]:
   体重  名前 性別   身長
2  51  佐藤  女  159
3  52  木村  女  164 

4. 条件に合致した行の特定の列を選択

In [9]: df.loc[df[u'性別']==u'女', u'体重']
Out[9]:
2    51
3    52
Name: 体重, dtype: int64 
In [10]: df.loc[df[u'性別']==u'女', [u'身長',u'体重']]
Out[10]:
    身長  体重
2  159  51
3  164  52 

5. そして、要約統計量

行列を選択した結果は DataFrame が返ってくる。なので、そのまま DataFrame の関数が使える。

In [11]: df.loc[df[u'性別']==u'女', [u'身長',u'体重']].describe()
Out[11]:
               身長         体重
count    2.000000   2.000000
mean   161.500000  51.500000
std      3.535534   0.707107
min    159.000000  51.000000
25%    160.250000  51.250000
50%    161.500000  51.500000
75%    162.750000  51.750000
max    164.000000  52.000000 

今回はこんなところで。