データフレームで加工したデータを結合させたいことありますよね?
そんな時はpandas.concatが便利です。
本記事ではpandas.concatの使い方についてわかりやすく説明しています。
pandas.concatとは
pandas.concatとはdataframeやsiresを結合できる関数です。
引数を変更することで行や列の指定や連結方法の指定ができます。
pandas.concatの使い方
pandas.concat()を実際に使ってみましょう。
本記事のコードは全てグーグルコラボラトリーで記述・動作を確認しています。
グーグルコラボラトリーとはgoogleアカウントを持っている人であれば、誰でも・無料で使うことができるpythonの対話型実行環境です。
データ分析に必要なライブラリが初めから搭載されていて、環境構築の必要がないため、python初心者には特にオススメです!
準備
まずはpandasのインポートです。
import pandas as pd
表(dataframe)も用意しましょう。
元となるdataframeは生徒Aさん、Bさん、Cさん、Dさんの国語、数学、英語のテスト結果です。
値は各行ごとに記述していきます。
d = [['国語', 51, 70, 35, 90], ['数学', 21, 0,55, 50], ['英語', 14, 74, 23, 67]]
df01 = pd.DataFrame(data=d, index=[0, 1,2], columns=['科目', 'A', 'B', 'C', 'D'])
df01
出力:
index | 科目 | A | B | C | D |
---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 |
1 | 数学 | 21 | 0 | 55 | 50 |
2 | 英語 | 14 | 74 | 23 | 67 |
追加させたいdataframeを準備します。今回は2つ作ります。
1つ目は各生徒の理科、社会のテスト結果です。
add_sub = [['理科', 94, 56, 18, 23], ['社会', 41, 0,68,47]]
df02 = pd.DataFrame(data=add_sub, index=[0, 1,], columns=['科目', 'A', 'B', 'C', 'D'])
df02
出力:
index | 科目 | A | B | C | D |
---|---|---|---|---|---|
0 | 理科 | 94 | 56 | 18 | 23 |
1 | 社会 | 41 | 0 | 68 | 47 |
2つ目は生徒Eさん、Fさん、Gさんの各科目のテスト結果です。
add_stu = [['国語', 100, 6, 34], ['数学', 92, 22, 53], ['英語', 44, 29, 20], ['理科', 44, 2, 43], ['社会', 61, 50, 32]]
df03 = pd.DataFrame(data=add_stu, index=(0, 1, 2, 3, 4), columns=('科目', 'E', 'F', 'G'))
df03
出力:
index | 科目 | E | F | G |
---|---|---|---|---|
0 | 国語 | 100 | 6 | 34 |
1 | 数学 | 92 | 22 | 53 |
2 | 英語 | 44 | 29 | 20 |
3 | 理科 | 44 | 2 | 43 |
4 | 社会 | 61 | 50 | 32 |
行の結合
初めにAさん達のテスト結果を結合してみましょう。df01の下にdf02を結合したいですね。
ここでpandas.concatの出番です。
plus_sub01 = pd.concat([df01, df02])
plus_sub01
出力:
index | 科目 | A | B | C | D |
---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 |
1 | 数学 | 21 | 0 | 55 | 50 |
2 | 英語 | 14 | 74 | 23 | 67 |
0 | 理科 | 94 | 56 | 18 | 23 |
1 | 社会 | 41 | 0 | 68 | 47 |
問題なく結合できました。しかし、indexがそれぞれのdataframeのものを引き継いでいて見づらいですね。
引数 ‘ignore_index’ をTrueにすることで、結合した表でindexを再度割り振り直すことができます。
plus_sub02 = pd.concat([df01, df02], ignore_index=True)
plus_sub02
出力:
index | 科目 | A | B | C | D |
---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 |
1 | 数学 | 21 | 0 | 55 | 50 |
2 | 英語 | 14 | 74 | 23 | 67 |
3 | 理科 | 94 | 56 | 18 | 23 |
4 | 社会 | 41 | 0 | 68 | 47 |
indexが見やすくなりました。
列の結合: axis=1
次にEさん、Fさん、Gさんのテスト結果をplus_sub02に結合してみましょう。
今回はdataframeを横に結合したいので、引数 ‘axis’ を1に指定します。
plus_stu01 = pd.concat([plus_sub02, df03], axis=1)
plus_stu01
出力:
index | 科目 | A | B | C | D | 科目 | E | F | G |
---|---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 国語 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 数学 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 英語 | 44 | 29 | 20 |
3 | 理科 | 94 | 56 | 18 | 23 | 理科 | 44 | 2 | 43 |
4 | 社会 | 41 | 0 | 68 | 47 | 社会 | 61 | 50 | 32 |
Eさん、Fさん、Gさんのdataframeにあった 「科目」列もそのまま結合してしまいました… これでは見にくいので、どうにかしたいです。
df03を加工して、「科目」列の無い表を新たに作成しましょう。
drop関数を使用して特定の列や行を削除できます。
df04 = df03.drop('科目', axis=1)
df04
出力:
index | E | F | G |
---|---|---|---|
0 | 100 | 6 | 34 |
1 | 92 | 22 | 53 |
2 | 44 | 29 | 20 |
3 | 44 | 2 | 43 |
4 | 61 | 50 | 32 |
「科目」列を削除したdf04を結合してみましょう。
plus_stu02 = pd.concat([plus_sub02, df04], axis=1)
plus_stu02
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
1 | 数学 | 21 | 0 | 55 | 50 | 92 | 22 | 53 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
3 | 理科 | 94 | 56 | 18 | 23 | 44 | 2 | 43 |
4 | 社会 | 41 | 0 | 68 | 47 | 61 | 50 | 32 |
これで見やすいDataFremeになりました。
欠損値のあるDataFrameの結合
dataframeを作成したときにindexとcolumnsを指定しました。indexとcolumnsを指定することで欠損値があっても結合できます。
試しにBさんの理科、社会の結果がないDataFrameを結合してみます。
初めにdf02からBさんの列を削除します。
df05 = df02.drop('B', axis=1)
df05
出力:
index | 科目 | A | C | D |
---|---|---|---|---|
0 | 理科 | 94 | 18 | 23 |
1 | 社会 | 41 | 68 | 47 |
df05をdf01に結合してみます。
plus_sub03 = pd.concat([df01, df05])
plus_sub03
出力:
index | 科目 | A | B | C | D |
---|---|---|---|---|---|
0 | 国語 | 51 | 70.0 | 35 | 90 |
1 | 数学 | 21 | 0.0 | 55 | 50 |
2 | 英語 | 14 | 74.0 | 23 | 67 |
0 | 理科 | 94 | NaN | 18 | 23 |
1 | 社会 | 41 | NaN | 68 | 47 |
Bさんの理科、社会のテスト結果がNaN (欠損値)として表示されました。
今度は行に欠損値がある場合を試してみましょう。
まずはdf04の数学の行を削除したdataframeの用意です。数学の行はindex1に指定したので、「index1」行をdrop関数で削除します。
df06 = df04.drop(1)
df06
出力:
index | E | F | G |
---|---|---|---|
0 | 100 | 6 | 34 |
2 | 44 | 29 | 20 |
3 | 44 | 2 | 43 |
4 | 61 | 50 | 32 |
次に用意したdf06をplus_sub02に結合します。
plus_stu03 = pd.concat([plus_sub02, df06], axis=1)
plus_stu03
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100.0 | 6.0 | 34.0 |
1 | 数学 | 21 | 0 | 55 | 50 | NaN | NaN | NaN |
2 | 英語 | 14 | 74 | 23 | 67 | 44.0 | 29.0 | 20.0 |
3 | 理科 | 94 | 56 | 18 | 23 | 44.0 | 2.0 | 43.0 |
4 | 社会 | 41 | 0 | 68 | 47 | 61.0 | 50.0 | 32.0 |
Eさん、Fさん、Gさんの数学の結果が欠損値になりました。
連結方法の指定: join
concatの引数 ‘join’ は連結方法を指定できます。デフォルトでouterが指定されていて、outerだと全ての行または列を結合します。innerに指定すると、欠損値を含む行を除いて結合することが可能です。
plus_stu03_inner = pd.concat([plus_sub02, df06], axis=1, join='inner')
plus_stu03_inner
出力:
index | 科目 | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|---|
0 | 国語 | 51 | 70 | 35 | 90 | 100 | 6 | 34 |
2 | 英語 | 14 | 74 | 23 | 67 | 44 | 29 | 20 |
3 | 理科 | 94 | 56 | 18 | 23 | 44 | 2 | 43 |
4 | 社会 | 41 | 0 | 68 | 47 | 61 | 50 | 32 |
欠損値のあるindex1の行が丸ごとなくなったことが確認できますね。
まとめ
今回は表(dataframe)を結合するpandas.concatについて紹介しました。pandas.concatを使うことで、縦にも横にも結合ができます。
今回の記事を見てpythonを勉強したいと思った人は関連記事も見てください。
効率的に勉強する方法について紹介しています。
コメント