【Pandas】データフレームからデータを抽出し、concatを使って連結させる場合に注意すること[Python]

  • URLをコピーしました!
目次

Pandas

前回、PythonのPandasで行名や列名を一括で変更する方法を紹介しました。

今回はPandasでデータフレームからデータを抽出し、concatを使って連結させる場合に注意することを紹介します。

まずはデータフレームを2つこんな感じで準備してみました。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

print(df1)
print("")
print(df2)

実行結果
   a  b  c  d  e
0  1  2  3  4  5
1  2  3  4  5  6
2  3  4  5  6  7

    a   b   c   d   e
0  10  20  30  40  50
1  20  30  40  50  60
2  30  40  50  60  70

これをconcat([データフレーム1, データフレーム2])を使って縦に連結させてみるとこうなります。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

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

print(df3)

実行結果
    a   b   c   d   e
0   1   2   3   4   5
1   2   3   4   5   6
2   3   4   5   6   7
0  10  20  30  40  50
1  20  30  40  50  60
2  30  40  50  60  70

concatについてはこれらの記事でも紹介していますので、よかったらどうぞ。

行名が被ってしまっているところもあるので、人によっては再インデックスしたくなることでしょう。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

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

df3_re = df3.reset_index(drop=True)

print(df3_re)

実行結果
    a   b   c   d   e
0   1   2   3   4   5
1   2   3   4   5   6
2   3   4   5   6   7
3  10  20  30  40  50
4  20  30  40  50  60
5  30  40  50  60  70

ここまではおさらい。

それでは始めていきましょう。

データフレームから抽出したデータを連結させる場合

先ほどのように単純に2つのデータフレームを連結させる場合、concatとそのオプション引数である「axis」を使えば思い通りに連結できます。

問題はデータフレームからデータを抽出し、それぞれを連結させる場合に起こります。

例えば先ほどの1つ目のデータフレーム「df1」の1行目(インデックスとして0)と2つ目のデータフレーム「df2」の1、2行目(インデックスとして1、2)を抽出し、縦方向に連結してみましょう。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

print(df1.iloc[0])
print("")
print(df2.iloc[0:2])
print("")

df4 = pd.concat([df1.iloc[0], df2.iloc[0:2]], axis=0)

print(df4)

実行結果
a    1
b    2
c    3
d    4
e    5
Name: 0, dtype: int64

    a   b   c   d   e
0  10  20  30  40  50
1  20  30  40  50  60

     0     a     b     c     d     e
a  1.0   NaN   NaN   NaN   NaN   NaN
b  2.0   NaN   NaN   NaN   NaN   NaN
c  3.0   NaN   NaN   NaN   NaN   NaN
d  4.0   NaN   NaN   NaN   NaN   NaN
e  5.0   NaN   NaN   NaN   NaN   NaN
0  NaN  10.0  20.0  30.0  40.0  50.0
1  NaN  20.0  30.0  40.0  50.0  60.0

先ほど2つのデータフレームを連結するのと同じように連結させたのにも関わらず、縦方向の連結となっていません。

これは抽出した段階で、片方(1行だけ抽出した方)がシリーズ(Series)になってしまっているのが原因です。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

print(type(df1.iloc[0]))
print(type(df2.iloc[0:2]))

実行結果
<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>

シリーズをconcatで連結させると今回のように意図しない動きをするので、注意しましょう。

対応策

対応策としては1行だけ抽出した段階でシリーズになってしまうので、再度データフレームに戻してやることが挙げられます。

その場合「シリーズ.to_frame()」とすることでデータフレームに変換することができます。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

print(df1.iloc[0].to_frame())
print(type(df1.iloc[0].to_frame()))

実行結果
   0
a  1
b  2
c  3
d  4
e  5
<class 'pandas.core.frame.DataFrame'>

これでデータフレームに戻すことができましたが、問題はもう一つあります。

データフレームから1行抽出し、シリーズとなったものを再度データフレームに変換すると行と列が入れ替わった形になってしまいます。

そこで最後に転置(.transpose()か.T)する必要があります。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

print(df1.iloc[0].to_frame().T)
print(type(df1.iloc[0].to_frame().T))

実行結果
   a  b  c  d  e
0  1  2  3  4  5
<class 'pandas.core.frame.DataFrame'>

これで連結させる準備ができましたので、実際に連結させてみましょう。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

df6 = pd.concat([df1.iloc[0].to_frame().T, df2.iloc[0:2]], axis=0)

print(df6)

実行結果
    a   b   c   d   e
0   1   2   3   4   5
0  10  20  30  40  50
1  20  30  40  50  60

これで2つのデータフレームから抽出したデータを縦方向に正しく連結させることができました。

ちなみに横方向の連結の場合でも1列のみ抽出するとシリーズになってしまうので、データフレームへの変換が必要になります。

ただこの場合は転置は必要ありません。

import pandas as pd

columnnames = ["a", "b", "c", "d" , "e"]

data1 = [[1, 2, 3, 4, 5],
        [2, 3, 4, 5, 6],
        [3, 4, 5, 6, 7]]

data2 = [[10, 20, 30, 40 ,50],
         [20, 30, 40, 50, 60],
         [30, 40, 50, 60, 70]]

df1 = pd.DataFrame(data1, columns=columnnames)
df2 = pd.DataFrame(data2, columns=columnnames)

df7 = pd.concat([df1.iloc[:,0].to_frame(), df2.iloc[:,1:4]], axis=1)

print(df7)

実行結果
   a   b   c   d
0  1  20  30  40
1  2  30  40  50
2  3  40  50  60

今回は多分ですがデータフレームを色々弄るようになると直面するだろう抽出したデータの連結に関して注意すること、その対応策をお話ししました。

次回はSciPyでSavitzky-Golay法を使ってデータの平滑化、一次微分、二次微分の方法を紹介します。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次