このエントリーをはてなブックマークに追加

Advent Calendar 2013 - 11

Python で解析! - DataFrame 7

今回は concat を取り上げる。10 月のデータと 11 月のデータを一つにまとめるとか、山田くんと佐藤くんが集めたデータを一つにまとめるとか…そんなシチュエーションを想定している。

1. 前回の補足

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

df4 = df1.join([df2, df3])
       体重  名前 性別   身長         誕生日 好きなもの
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' を指定したのと同じになる。

df1.join([df2, df3], how='left')
       体重  名前 性別   身長         誕生日 好きなもの
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' を指定することができる。

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

'outer' も指定できる。

df1.join([df2, df3], how='outer')
       体重   名前   性別   身長         誕生日 好きなもの
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' は指定できない。

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

一つだけなら OK。

df1.join(df2, how='right')
       体重   名前   性別   身長         誕生日
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 のための準備を

import pandas as pd

f1 = 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'])

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'])
df1
       体重  名前 性別   身長
3B005  79  山田    181
3B003  71  鈴木    173
3B002  51  佐藤    159
3B001  52  木村    164

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

3. で、 concat を

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

df3 = pd.concat([df1, df2])
df3
       体重  名前   性別         誕生日   身長
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 が同じでも関係がなく、別のレコードして追加される。同じ名前のカラムは統合され、そうでないものは追加される。

df3.columns

Index([u'体重', u'名前', u'性別', u'誕生日', u'身長'], dtype=object)

df3.index

Index([u'3B005', u'3B003', u'3B002', u'3B001', u'3B004', u'3B005', u'3B003', u'3B002'], dtype=object)

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

df3.index.is_unique

False

今回はこんなところで。