【はじめに】
Pythonライブラリの「Pandas」の中で、DataFrameを結合する方法はいくつかあります。
今回はその中でも「concat」、「merge」、「join」について、それぞれの違いに触れながら紹介していきます。
本記事の内容
- pandasのインポート
- csvファイルの読み込み
- 列を取得する
- DataFrameを結合する | concat()
- DataFrameを結合する | merge()
- DataFrameを結合する | join()
【pandasのインポート】
import pandas as pd
【csvファイルの読み込み】
「1920年から2015年までの全国の人口推移のデータ」を使用します。
df = pd.read_csv('data.csv', encoding='shift-jis')
df
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 | 2359183 | 1244322 | 1114861 |
1 | 2 | 青森県 | 大正 | 9 | 1920 | 756454 | 381293 | 375161 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 | 845540 | 421069 | 424471 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 | 961768 | 485309 | 476459 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 | 898537 | 453682 | 444855 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
934 | 43 | 熊本県 | 平成 | 27 | 2015 | 1786170 | 841046 | 945124 |
935 | 44 | 大分県 | 平成 | 27 | 2015 | 1166338 | 551932 | 614406 |
936 | 45 | 宮崎県 | 平成 | 27 | 2015 | 1104069 | 519242 | 584827 |
937 | 46 | 鹿児島県 | 平成 | 27 | 2015 | 1648177 | 773061 | 875116 |
938 | 47 | 沖縄県 | 平成 | 27 | 2015 | 1433566 | 704619 | 728947 |
939 rows × 8 columns |
私のGitHubに「nikkei.csv」としてアップロードしてあるので、下記コマンドでダウンロードすれば簡単に準備できます。
curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Pandas/data.csv -O
【列を取得する】
例として、
- 「都道府県コード、都道府県名、元号、和暦(年)、西暦(年)」のデータ
- 「人口(総数)、人口(男)、人口(女)」のデータ
- 「大正、昭和(平成以外)」のデータ(平成以外)
- 「平成」のデータ
それぞれのデータに分けて、新しくデータフレームを作成します。
df_1 = df[['都道府県コード', '都道府県名', '元号', '和暦(年)','西暦(年)']]
df_1.head()
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | |
---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 |
1 | 2 | 青森県 | 大正 | 9 | 1920 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 |
df_2 = df[['人口(総数)', '人口(男)', '人口(女)']]
df_2.head()
人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|
0 | 2359183 | 1244322 | 1114861 |
1 | 756454 | 381293 | 375161 |
2 | 845540 | 421069 | 424471 |
3 | 961768 | 485309 | 476459 |
4 | 898537 | 453682 | 444855 |
df_3 = df[df['元号']!='平成']
df_3.tail()
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
652 | 43 | 熊本県 | 昭和 | 60 | 1985 | 1837747 | 872932 | 964815 |
653 | 44 | 大分県 | 昭和 | 60 | 1985 | 1250214 | 593014 | 657200 |
654 | 45 | 宮崎県 | 昭和 | 60 | 1985 | 1175543 | 558355 | 617188 |
655 | 46 | 鹿児島県 | 昭和 | 60 | 1985 | 1819270 | 856493 | 962777 |
656 | 47 | 沖縄県 | 昭和 | 60 | 1985 | 1179097 | 581102 | 597995 |
df_4 = df[df['元号']=='平成']
df_4.head()
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
652 | 43 | 熊本県 | 昭和 | 60 | 1985 | 1837747 | 872932 | 964815 |
653 | 44 | 大分県 | 昭和 | 60 | 1985 | 1250214 | 593014 | 657200 |
654 | 45 | 宮崎県 | 昭和 | 60 | 1985 | 1175543 | 558355 | 617188 |
655 | 46 | 鹿児島県 | 昭和 | 60 | 1985 | 1819270 | 856493 | 962777 |
656 | 47 | 沖縄県 | 昭和 | 60 | 1985 | 1179097 | 581102 | 597995 |
ポイント
- 条件に合う列の値を取得する場合は、
DataFrame['カラム名']=='条件'
- 条件以外の列の値を取得する場合は、
DataFrame['カラム名']!='条件'
- 条件の値より大きい値を取得する場合は、
DataFrame['カラム名']>'条件'
- 条件の値より小さい値を取得する場合は、
DataFrame['カラム名']<'条件'
【DataFrameを結合する | concat()】
-
pd.concat()
関数では括弧内に結合したいpandas.DataFrameもしくはpandas.Seriesを角括弧[]で指定します。 - 列方向に結合したい場合は、
axis
オプションに「1」を指定します。
pd.concat([df_1, df_2], axis=1)
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 | 2359183 | 1244322 | 1114861 |
1 | 2 | 青森県 | 大正 | 9 | 1920 | 756454 | 381293 | 375161 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 | 845540 | 421069 | 424471 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 | 961768 | 485309 | 476459 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 | 898537 | 453682 | 444855 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
934 | 43 | 熊本県 | 平成 | 27 | 2015 | 1786170 | 841046 | 945124 |
935 | 44 | 大分県 | 平成 | 27 | 2015 | 1166338 | 551932 | 614406 |
936 | 45 | 宮崎県 | 平成 | 27 | 2015 | 1104069 | 519242 | 584827 |
937 | 46 | 鹿児島県 | 平成 | 27 | 2015 | 1648177 | 773061 | 875116 |
938 | 47 | 沖縄県 | 平成 | 27 | 2015 | 1433566 | 704619 | 728947 |
939 rows × 8 columns |
- 行方向に結合したい場合は、
axis
オプションに「0」を指定します。
pd.concat([df_3, df_4], axis=0)
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 | 2359183 | 1244322 | 1114861 |
1 | 2 | 青森県 | 大正 | 9 | 1920 | 756454 | 381293 | 375161 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 | 845540 | 421069 | 424471 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 | 961768 | 485309 | 476459 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 | 898537 | 453682 | 444855 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
934 | 43 | 熊本県 | 平成 | 27 | 2015 | 1786170 | 841046 | 945124 |
935 | 44 | 大分県 | 平成 | 27 | 2015 | 1166338 | 551932 | 614406 |
936 | 45 | 宮崎県 | 平成 | 27 | 2015 | 1104069 | 519242 | 584827 |
937 | 46 | 鹿児島県 | 平成 | 27 | 2015 | 1648177 | 773061 | 875116 |
938 | 47 | 沖縄県 | 平成 | 27 | 2015 | 1433566 | 704619 | 728947 |
939 rows × 8 columns |
【DataFrameを結合する | merge()】
-
pd.merge()
関数では括弧内に第一引数leftと第二引数rightに結合する2つのpandas.DataFrameを指定します。 - 結合するDataFrameに重複した列が存在する場合に使用します。
df_5 = df[['都道府県コード', '都道府県名', '元号', '和暦(年)','西暦(年)', '人口(総数)']]
df_5.head()
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | |
---|---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 | 2359183 |
1 | 2 | 青森県 | 大正 | 9 | 1920 | 756454 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 | 845540 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 | 961768 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 | 898537 |
df_2 = df[['人口(総数)', '人口(男)', '人口(女)']]
df_2.head()
人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|
0 | 2359183 | 1244322 | 1114861 |
1 | 756454 | 381293 | 375161 |
2 | 845540 | 421069 | 424471 |
3 | 961768 | 485309 | 476459 |
4 | 898537 | 453682 | 444855 |
# df_5とdf_2で重複している「人口(総数)」の列をまとめて結合
_df = pd.merge(df_5, df_2)
_df
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 | 2359183 | 1244322 | 1114861 |
1 | 2 | 青森県 | 大正 | 9 | 1920 | 756454 | 381293 | 375161 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 | 845540 | 421069 | 424471 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 | 961768 | 485309 | 476459 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 | 898537 | 453682 | 444855 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
936 | 43 | 熊本県 | 平成 | 27 | 2015 | 1786170 | 841046 | 945124 |
937 | 44 | 大分県 | 平成 | 27 | 2015 | 1166338 | 551932 | 614406 |
938 | 45 | 宮崎県 | 平成 | 27 | 2015 | 1104069 | 519242 | 584827 |
939 | 46 | 鹿児島県 | 平成 | 27 | 2015 | 1648177 | 773061 | 875116 |
940 | 47 | 沖縄県 | 平成 | 27 | 2015 | 1433566 | 704619 | 728947 |
941 rows × 8 columns |
ポイント
pd.merge()
関数を使用すると行数が増えることがあります。
今回は939行だったデータから941行に増えています。
人口(総数)をキーにしてデータを結合していますが、df_5に同じ人口(総数)「832832」が複数含まれていました。
この場合df_2の人口(総数)「832832」に対して、すべてのパターンで結合するためデータ行が増えることになリます。
df_5[df_5['人口(総数)']==832832]
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | |
---|---|---|---|---|---|---|
628 | 19 | 山梨県 | 昭和 | 60 | 1985 | 832832 |
932 | 41 | 佐賀県 | 平成 | 27 | 2015 | 832832 |
df_2[df_2['人口(総数)']==832832]
人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|
628 | 832832 | 407910 | 424922 |
932 | 832832 | 393073 | 439759 |
_df[_df['人口(総数)']==832832]
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
628 | 19 | 山梨県 | 昭和 | 60 | 1985 | 832832 | 407910 | 424922 |
629 | 19 | 山梨県 | 昭和 | 60 | 1985 | 832832 | 393073 | 439759 |
630 | 41 | 佐賀県 | 平成 | 27 | 2015 | 832832 | 407910 | 424922 |
631 | 41 | 佐賀県 | 平成 | 27 | 2015 | 832832 | 393073 | 439759 |
【DataFrameを結合する | join()】
-
DataFrame.join()
はpandas.DataFrameのメソッドのみとなります。 - インデックスをキーに結合します。
df_1 = df[['都道府県コード', '都道府県名', '元号', '和暦(年)','西暦(年)']]
df_1.head()
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | |
---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 |
1 | 2 | 青森県 | 大正 | 9 | 1920 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 |
df_2 = df[['人口(総数)', '人口(男)', '人口(女)']]
df_2.head()
人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|
0 | 2359183 | 1244322 | 1114861 |
1 | 756454 | 381293 | 375161 |
2 | 845540 | 421069 | 424471 |
3 | 961768 | 485309 | 476459 |
4 | 898537 | 453682 | 444855 |
df_1.join(df_2)
# pd.concat([df_1, df_2], axis=1)と同じ
都道府県コード | 都道府県名 | 元号 | 和暦(年) | 西暦(年) | 人口(総数) | 人口(男) | 人口(女) | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 北海道 | 大正 | 9 | 1920 | 2359183 | 1244322 | 1114861 |
1 | 2 | 青森県 | 大正 | 9 | 1920 | 756454 | 381293 | 375161 |
2 | 3 | 岩手県 | 大正 | 9 | 1920 | 845540 | 421069 | 424471 |
3 | 4 | 宮城県 | 大正 | 9 | 1920 | 961768 | 485309 | 476459 |
4 | 5 | 秋田県 | 大正 | 9 | 1920 | 898537 | 453682 | 444855 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
934 | 43 | 熊本県 | 平成 | 27 | 2015 | 1786170 | 841046 | 945124 |
935 | 44 | 大分県 | 平成 | 27 | 2015 | 1166338 | 551932 | 614406 |
936 | 45 | 宮崎県 | 平成 | 27 | 2015 | 1104069 | 519242 | 584827 |
937 | 46 | 鹿児島県 | 平成 | 27 | 2015 | 1648177 | 773061 | 875116 |
938 | 47 | 沖縄県 | 平成 | 27 | 2015 | 1433566 | 704619 | 728947 |
939 rows × 8 columns |
ポイント
- 同じ行数のDataFrame同士を結合する場合、重複する列を片方のデータから削除してから
concat()
関数もしくはDataFrame.join()
で結合する方が良いと思います。 - DataFrameとSeriesを結合する場合は、
concat()
関数のみ使用できます。
【おわりに】
今回はその中でも「concat」、「merge」、「join」について、それぞれの違いに触れながら紹介しました。
データ形式や使用用途に応じて結合方法を選ぶ必要がありますが、個人的にはpd.concat()
関数が万能なのではないかと思います。
今回、使用したCSVファイルやJupyter NotebookはGitHubに公開しています。
Jupyter Notebookは下記コマンドでダウンロードできるので、自由に使って是非練習してみてください。
$ curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Pandas/pandasでDataFrameを結合する.ipynb -O