pd.concatはデータフレーム同士を結合するためによく用いられる関数の一つで、引数axisをしてすることで、縦方向か横方向に結合するか指定できます。
公式ドキュメント
一般的にただその方向に結合するように思われていますが、実はデータフレームのindex同士を参照して結合していることをご存知でしたか?
今回はこのことについてお話しします。
全コードはこちらのGithubにも載せているので、参照してください。
サンプルデータ
今回使用するデータは以下の通りになります。わかりやすいように超シンプルにしています。
佐藤太郎さん、山田二郎さん、鈴木三郎さんという3人の姓と名だけがそれぞれ入っている2つのデータフレームがあるとします。これらを横方向に結合する場合を考えます。
import pandas as pd
import numpy as np
df1 = pd.DataFrame({'last_name':['佐藤','山田','鈴木']})
df2 = pd.DataFrame({'first_name':['太郎','二郎','三郎']})
display(df1)
display(df2)
よくあるconcatでの結合
これら2つのデータフレームdf1, df2を横方向に結合してみましょう
pd.concat([df1, df2],axis=1)
無事結合できましたね!このとき、df2がdf1の横に丸々くっついたように見えます。
df1のindexの順番を変更した場合
ここからが本題です!
続いて、df1のindexの順番だけを変更して結合してみましょう。
まず、indexの変更です。
df1.index = [1,0,2]
display(df1)
このとき姓の順番は変わっていませんが、indexの順番のみが変わっています。
では、この場合結合したらどのようになるのでしょうか。
pd.concat([df1, df2],axis=1)
さっきと結果が変わり、山田二郎さんが山田太郎さんに、佐藤太郎さんが佐藤二郎さんになってしまいました!
これは何故でしょうか?
実は、concatで横方向に結合する際は同じindex同士で結合しているからなんです!
なので、横方向に結合する際はデータフレーム同士を単に横に結合しているというのは厳密には正しい言い方ではありません。
この状況が起こりうる状況
そもそも、indexが前後したり飛んでしまう状況は実務上あり得るのでしょうか。
私の経験上の話にはなりますが、このような状況はよくあると思います。
(自分のデータ処理スキルが低いだけかもしれませんが、、、)
例えば、
- あるデータセットから一部の列を抜き出して、処理をする場合。
- 特に、並び替えて処理しreset_index()で新しくindexを振ってしまう場合。
といったことが考えられます。
もし、上のようなことを意識したくないのであれば、一部の列を抜き出す際にkeyとなる列も取り出してしまい、加工後pd.merge関数を使って結合する方がわかりやすく確実です。
しかし、大規模なデータになればなるほどpd.mergeは実行時間がとてもかかるため、使い分けが大事です。
まとめ
今回はpd.concatで横方向に結合する際の注意点についてお話ししました。
実はただ横方向に結合するのではなく、indexをkeyとして結合しているということが重要です。
動きがよくわからないからconcatを避けてmergeを使っている方なども是非これを機会に適切に使ってくれれば幸いです。
全コードはこちら
コメント