Pythonのデータ解析支援ライブラリPandas 〜その9 データフレームの連結:concat〜

スポンサーリンク

データ解析支援ライブラリPandas

前回はデータ解析支援ライブラリPandasのassignで列を、appendで列を追加する方法を解説しました。

Pythonのデータ解析支援ライブラリPandas 〜その8 行、列の追加:assign、append〜
データ解析支援ライブラリPandas前回はデータ解析支援ライブラリPandasで行や列を追加する方法の基本を解説しました。今回も行や列を追加する方法ですが、今回はassignとappendというコマンドを用いた方法...

今回は追加するという流れでデータフレームを連結する方法を解説していきたいと思います。

ということで今回もまずは準備から。

今回はデータフレームを連結する方法ということで、複数のデータを準備しました。

Pythonでファイル数、行数、列数を指定してダミーデータのファイルを生成するプログラムを作ってみた
ランダムデータのファイルが欲しい!前にjunney様より「グラフタイトルをファイル名としたい」というご質問を頂き、答えてみました。ただどうやら他にもプログラムが動いていない部分があるようで、再度ご質問を頂きました。...

こちらのデータをダウンロードして、展開すると以下の4つのファイルが入っています。

  • python-pandas-10_data1.txt
  • python-pandas-10_data2.txt
  • python-pandas-10_data3.txt
  • python-pandas-10_data4.txt

とりあえずこの4つのデータを読み込んで表示してみましょう。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df1

実行結果
mport pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df2

実行結果
mport pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df3

実行結果
mport pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df4

実行結果

同じように見えますが、違うのは列名や行名です。

1番「python-pandas-10_data1.txt」のデータは、列名が「value_1-X」、行名が「data_1-X」となっています。

2番「python-pandas-10_data2.txt」のデータは、列名が「value_1-X」、行名が「data_2-X」となっています。

3番「python-pandas-10_data3.txt」のデータは、列名が「value_2-X」、行名が「data_1-X」となっています。

4番「python-pandas-10_data4.txt」のデータは、列名が「value_2-X」、行名が「data_2-X」となっています。

つまり1番と2番では列名は同じで、行名は違い、1番と3番では列名が異なり、行名が同じ、1番と4番では列名も行名も異なるということです。

では試していきましょう。

スポンサーリンク

concatでデータフレームを連結:列名が同じで行名が違う場合

データフレームを連結するには、concatというコマンドを用い、「データフレーム名 = pd.concat([データフレーム1, データフレーム2])」とします。

まずは列名が同じで行名が違う、1番のデータと2番のデータを連結してみましょう。

その場合、「df_12 = pd.concat[(df1, df2)]」となります。

ということで試してみましょう。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_12 = pd.concat([df1, df2])

df_12

実行結果

列名が同じなので縦に連結されました。

スポンサーリンク

concatでデータフレームを連結:列名が違い、行名が同じ場合

列名が同じで、行名が異なる場合、縦に連結されました。

では列名が違い、行名が同じ場合、自動で横に連結されるのでしょうか?

ということで1番と3番のデータを連結してみましょう。

「df_13 = pd.concat([df1, df3])」を追加して、実行してみます。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_13 = pd.concat([df1, df3])

df_13

実行結果

なんと予想に反して、行も列も新しいものだと認識されてしまいました。

実はconcatのコマンドは、縦に連結するのが基本なのです。

横に連結するには、オプションとしてaxis=1を追加します。

つまり「df_13 = pd.concat([df1, df3], axis=1)」とする必要があるわけです。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_13 = pd.concat([df1, df3], axis=1)

df_13

実行結果
スポンサーリンク

横に連結する場合はaxis=1、では縦に連結する場合は?

先ほど横に連結するためのオプションはaxis=1を追加すると解説しました。

では縦に連結する場合はどうしたらいいのでしょうか?

答えはaxis=0となります。

再度、1番と2番のデータを連結して試してみましょう。

まずはオプションなし。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_12 = pd.concat([df1, df2])

df_12

実行結果

次にオプションとして、axis=0を追加してみます。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_12 = pd.concat([df1, df2], axis=0)

df_12

実行結果

オプションがない場合と同じ結果になりました。

次にオプションとして、axis=1を追加してみましょう。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_12 = pd.concat([df1, df2], axis=1)

df_12

実行結果

横に追加するのですが、行名が一致していないので、縦にも横にも新しい場所に追加されました。

axis=0が縦に追加、axis=1が横に追加としたら、axis=2とするとどうなるでしょうか?

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_12 = pd.concat([df1, df2], axis=2)

df_12

実行結果

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-36-8edfddc30224> in <module>
      6 df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)
      7 
----> 8 df_12 = pd.concat([df1, df2], axis=2)
      9 
     10 df_12

/opt/anaconda3/lib/python3.7/site-packages/pandas/core/reshape/concat.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, sort, copy)
    253         verify_integrity=verify_integrity,
    254         copy=copy,
--> 255         sort=sort,
    256     )
    257 

/opt/anaconda3/lib/python3.7/site-packages/pandas/core/reshape/concat.py in __init__(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy, sort)
    368             axis = DataFrame._get_axis_number(axis)
    369         else:
--> 370             axis = sample._get_axis_number(axis)
    371 
    372         # Need to flip BlockManager axis in the DataFrame special case

/opt/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in _get_axis_number(cls, axis)
    409             except KeyError:
    410                 pass
--> 411         raise ValueError("No axis named {0} for object type {1}".format(axis, cls))
    412 
    413     @classmethod

ValueError: No axis named 2 for object type <class 'pandas.core.frame.DataFrame'>

そんな値はないとエラーが表示されました。

スポンサーリンク

concatでデータフレームを連結:列名も行名も違う場合

次に列名も行名も違う場合を試してみましょう。

ということで1番のデータと4番のデータを連結してみます。

まずはオプションなし、つまり縦に連結してみましょう。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_14 = pd.concat([df1, df4])

df_14

実行結果

一致しないので、縦にも横にも新しい場所に追加されました。

次にaxis=1、つまり横に追加してみましょう。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_14 = pd.concat([df1, df4], axis=1)

df_14

実行結果

こちらも縦でも横でも名前は一致しないので、新しい場所に連結されました。

スポンサーリンク

concatでデータフレームを連結:列名も行名も同じ場合

最後に列名も行名も同じ場合を試してみましょう。

つまり1番のデータと1番のデータを連結してみます。

まずはオプションなしで、縦に連結してみます。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_11= pd.concat([df1, df1])

df_11

実行結果

全く同じデータを連結しても大丈夫なのは少し驚きました。

とりあえずちゃんと縦に連結できています。

では横に連結する、つまりオプションとしてaxis=1を追加してみましょう。

import pandas as pd

df1 = pd.read_csv("python-pandas-10_data1.txt", index_col=0)
df2 = pd.read_csv("python-pandas-10_data2.txt", index_col=0)
df3 = pd.read_csv("python-pandas-10_data3.txt", index_col=0)
df4 = pd.read_csv("python-pandas-10_data4.txt", index_col=0)

df_11= pd.concat([df1, df1], axis=1)

df_11

実行結果

こちらも問題なく横に連結できました。

ということで今回はconcatというコマンドを使って、データフレームを連結する方法を解説しました。

ただここで少し疑問が生まれます。

今回のように同じ行名、列名を含むデータを連結すると、同じ行名、列名が複数回含まれてしまうこともあります。

例えばすぐ上の同じ行名、列名をもつデータを横に連結した例では、実行結果として「value_1-1」が2回、「value_1-2」が2回…といったように同じ列名が2回ずつ含まれています。

これがどのように処理されるのか?

次回色々と試してみたいと思います。

ということで今回はこんな感じで。

コメント

タイトルとURLをコピーしました