【Pandas DataFrame】行・列の追加・結合 [concat]

 ※ 本記事は広告・プロモーションを含みます。
Pandas

たっきん(Twitter)です!

今回は、DataFrameに行・列を追加したり、他のDataFrameSeriesを結合したりする方法について説明していきます。

DataFrameに行・列を追加、結合する機会も比較的多いと思いますので、ここでしっかり学習していきましょう!

行・列の追加は専用のメソッド(関数)としてassign()insert()が用意されていますが、ここでは代入方式での追加方法で説明していきます。

理由は代入方式での追加の仕方を覚えていれば必要十分だからです。

insert()は任意の位置の行・列を指定して挿入することができますが、基本的に“ラベル名”でデータにアクセスすることを踏まえると、挿入位置を指定することにあまり意味はないからです。

実際、僕もシステムトレード開発を通して行・列の追加にassign()insert()を使ったことはなく、基本的に代入方式を使用してきました。

行方向への追加メソッドとしてappend()がありますが、version 1.4.0より非推奨となりました。
将来的には削除されるメソッドになるので、使用しないようにしましょう!

【API Reference】
 ・pandas.DataFrame.append
 ・pandas.Series.append

代入方式では次の3つのデータ型での代入が可能ですので、1つずつサンプルコードを使って説明していきます。

  • 単一
  • リスト
  • Series

また、データの追加に合わせて、concat()を使ったデータの結合方法についても説明してきます。

concat()は複数のDataFrameまたは、Seriesを結合して1つのDataFrameを生成するメソッドになります。

複数のDataFrameを結合させて1つのDataFrameにまとめたい場合はconcat()を使うことになるので、この機会に使い方を覚えてしまいましょう!

Pandasに関する記事を多数書いてます

「列」の追加・結合

列を追加する場合は次のように記述します。

  • .loc[:, "列ラベル"] = 単一 or リスト or Series

の場合に限り、インデックス[]での記述も可能です。
 ・df["列ラベル"]= 単一 or リスト or Series

サンプルコードとして、次のDataFrame型データに各代入方式で列を追加する方法を説明してきます。

import pandas as pd

ohlc_data = [
    ["2020/4/6", 108.432],
    ["2020/4/7", 109.252],
    ["2020/4/8", 108.799],
    ["2020/4/9", 108.854],
    ["2020/4/10", 108.545],
]
df = pd.DataFrame(ohlc_data, columns=["datetime", "open"])
df.set_index("datetime", inplace=True)
print(df)
"""
              open
datetime          
2020/4/6   108.432
2020/4/7   109.252
2020/4/8   108.799
2020/4/9   108.854
2020/4/10  108.545
"""

列の追加(単一)

単一のデータで代入すると、全ての行が代入値に変更されます。

# 列を単一データで追加
df.loc[:, "high"] = 0.0
# df["high"] = 0.0 と記述してもOK
print(df)
"""
                     追加
                      ↓
              open  high
datetime                
2020/4/6   108.432   0.0
2020/4/7   109.252   0.0
2020/4/8   108.799   0.0
2020/4/9   108.854   0.0
2020/4/10  108.545   0.0
"""

列の追加(リスト)

リストで代入すると、リストの要素順に各行の値が変更されます。

リストの要素数が追加先DataFrameの行数と一致していないとValueErrorが発生しますので、リストで追加する際は要素数に注意しましょう!

# 列をリストで追加
df.loc[:, "low"] = [98.403, 98.680, 98.514, 98.218, 98.341]
# df["low"] = [98.403, 98.680, 98.514, 98.218, 98.341] と記述してもOK
print(df)
"""
                             追加
                              ↓
              open  high     low
datetime                        
2020/4/6   108.432   0.0  98.403
2020/4/7   109.252   0.0  98.680
2020/4/8   108.799   0.0  98.514
2020/4/9   108.854   0.0  98.218
2020/4/10  108.545   0.0  98.341
"""

# 行数が一致していないと"ValueError"が発生
df.loc[:, "low2"] = [98.403, 98.680]
"""
ValueError: Length of values (2) does not match length of index (5)
"""

列の追加(Series)

以前書いた記事で「単一の列を抽出した場合はSeries型で取得される」と説明しました。

これとは逆にSeries型で代入すると、列として追加されます。

# Seriesデータ作成
data = [109.252, 108.799, 108.854, 108.545, 108.515]
index = df.index
sr_new = pd.Series(data, index, name="new_col")
print(sr_new)
"""
datetime
2020/4/6     109.252
2020/4/7     108.799
2020/4/8     108.854
2020/4/9     108.545
2020/4/10    108.515
Name: new_col, dtype: float64
"""

# 列をSeriesで追加
df.loc[:, "close"] = sr_new
# df["close"] = sr_new と記述してもOK
print(df)
"""
                                     追加
                                      ↓
              open  high     low    close
datetime                                 
2020/4/6   108.432   0.0  98.403  109.252
2020/4/7   109.252   0.0  98.680  108.799
2020/4/8   108.799   0.0  98.514  108.854
2020/4/9   108.854   0.0  98.218  108.545
2020/4/10  108.545   0.0  98.341  108.515
"""

ちなみに、Seriesで追加する場合、追加先DataFrameの行数とSeriesのデータ数が一致していなくてもエラーは発生しません。

その代わり、不足分は欠損値NaNで埋められます。

# Seriesデータ作成(2行分のみ)
data = [109.252, 108.799]
index = ["2020/4/6", "2020/4/7"]
sr_new2 = pd.Series(data, index, name="new_col")
print(sr_new2)
"""
2020/4/6    109.252
2020/4/7    108.799
Name: new_col, dtype: float64
"""

# 列をSeriesで追加(不足分は"NaN"が設定される)
df["close2"] = sr_new2
print(df)
"""
                                              追加
                                               ↓
              open  high     low    close   close2
datetime                                          
2020/4/6   108.432   0.0  98.403  109.252  109.252
2020/4/7   109.252   0.0  98.680  108.799  108.799
2020/4/8   108.799   0.0  98.514  108.854      NaN
2020/4/9   108.854   0.0  98.218  108.545      NaN
2020/4/10  108.545   0.0  98.341  108.515      NaN
"""

列の結合 [concat()]

pandas.concat()で列方向に結合したい場合は引数にaxis=1を設定します。

結合後のデータは返り値で受け取ります。

以下、"low"データをSeriesで作成してDataFrameに結合するサンプルコードになります。

import pandas as pd

# 結合前データ1をDataFrameで作成
ohlc_data = [
    ["2020/4/6", 108.432, 119.393],
    ["2020/4/7", 109.252, 119.294],
    ["2020/4/8", 108.799, 119.109],
    ["2020/4/9", 108.854, 119.071],
    ["2020/4/10", 108.545, 118.615],
]
df1 = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high"])
df1.set_index("datetime", inplace=True)
print(df1)
"""
              open     high
datetime                   
2020/4/6   108.432  119.393
2020/4/7   109.252  119.294
2020/4/8   108.799  119.109
2020/4/9   108.854  119.071
2020/4/10  108.545  118.615
"""

# 結合前データ2をSeriesで作成
data = [98.403, 98.680, 98.514, 98.218, 98.341]
index = df1.index
sr2 = pd.Series(data, index, name="low")
print(sr2)
"""
datetime
2020/4/6     98.403
2020/4/7     98.680
2020/4/8     98.514
2020/4/9     98.218
2020/4/10    98.341
Name: low, dtype: float64
"""

# データ1(DataFrame)とデータ2(Series)を列方向に結合
df_c = pd.concat([df1, sr2], axis=1)
print(df_c)
"""
              open     high     low
datetime                           
2020/4/6   108.432  119.393  98.403
2020/4/7   109.252  119.294  98.680
2020/4/8   108.799  119.109  98.514
2020/4/9   108.854  119.071  98.218
2020/4/10  108.545  118.615  98.341
"""

DataFrame同士を結合することも可能です。

以下、"low""close"データをDataFrameで作成して元のDataFrameに結合するサンプルコードになります。

import pandas as pd

# 結合前データ1をDataFrameで作成
ohlc_data = [
    ["2020/4/6", 108.432, 119.393],
    ["2020/4/7", 109.252, 119.294],
    ["2020/4/8", 108.799, 119.109],
    ["2020/4/9", 108.854, 119.071],
    ["2020/4/10", 108.545, 118.615],
]
df1 = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high"])
df1.set_index("datetime", inplace=True)
print(df1)
"""
              open     high
datetime                   
2020/4/6   108.432  119.393
2020/4/7   109.252  119.294
2020/4/8   108.799  119.109
2020/4/9   108.854  119.071
2020/4/10  108.545  118.615
"""

# 結合前データ2をDataFrameで作成
ohlc_data = [
    ["2020/4/6", 98.403, 109.252],
    ["2020/4/7", 98.680, 108.799],
    ["2020/4/8", 98.514, 108.854],
    ["2020/4/9", 98.218, 108.545],
    ["2020/4/10", 98.341, 108.515],
]
df2 = pd.DataFrame(ohlc_data, columns=["datetime", "low", "close"])
df2.set_index("datetime", inplace=True)
print(df2)
"""
              low    close
datetime                  
2020/4/6   98.403  109.252
2020/4/7   98.680  108.799
2020/4/8   98.514  108.854
2020/4/9   98.218  108.545
2020/4/10  98.341  108.515
"""

# データ1(DataFrame)とデータ2(DataFrame)を列方向に結合
df_c = pd.concat([df1, df2], axis=1)
print(df_c)
"""
              open     high     low    close
datetime                                    
2020/4/6   108.432  119.393  98.403  109.252
2020/4/7   109.252  119.294  98.680  108.799
2020/4/8   108.799  119.109  98.514  108.854
2020/4/9   108.854  119.071  98.218  108.545
2020/4/10  108.545  118.615  98.341  108.515
"""

「行」の追加・結合

行を追加する場合は次のように記述します。

  • .loc["行ラベル"] = 単一 or リスト or Series
    (または、.loc["行ラベル", :] = 単一 or リスト or Series

サンプルコードとして、次のDataFrame型データに各代入方式で行を追加する方法を説明してきます。

import pandas as pd

ohlc_data = [
    ["2020/4/6", 108.432, 119.393, 98.403, 109.252],
    ["2020/4/7", 109.252, 119.294, 98.680, 108.799],
]

df = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high", "low", "close"])
df.set_index("datetime", inplace=True)
print(df)
"""
             open     high     low    close
datetime                                   
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
"""

行の追加(単一)

単一のデータで代入すると、全ての列が代入値に変更されます。

# 行を単一データで追加
df.loc["2020/4/8"] = 0.0
# df.loc["2020/4/8", :] = 0.0 と記述してもOK
print(df)
"""
             open     high     low    close
datetime                                   
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
2020/4/8    0.000    0.000   0.000    0.000  <- 追加
"""

行の追加(リスト)

リストで代入すると、リストの要素順に各列の値が変更されます。

リストの要素数が追加先DataFrameの列数と一致していないとValueErrorが発生しますので、リストで追加する際は要素数に注意しましょう!

# 行をリストで追加
df.loc["2020/4/9"] = [108.854, 119.071, 98.218, 108.545]
# df.loc["2020/4/9", :] = [108.854, 119.071, 98.218, 108.545] と記述してもOK
print(df)
"""
             open     high     low    close
datetime                                   
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
2020/4/8    0.000    0.000   0.000    0.000
2020/4/9  108.854  119.071  98.218  108.545  <- 追加
"""

# 列数が一致していないと"ValueError"が発生
df.loc["2020/4/10", :] = [108.854, 119.071]
"""
ValueError: could not broadcast input array from shape (2,) into shape (4,)
"""

行の追加(Series)

以前書いた記事で「単一の行を抽出した場合はSeries型で取得される」と説明しました。

これとは逆にSeries型で代入すると、行として追加されます。

# Seriesデータ作成
data = [108.545, 118.615, 98.341, 108.515]
index = df.columns
sr_new = pd.Series(data, index, name="new_row")
print(sr_new)
"""
open     108.545
high     118.615
low       98.341
close    108.515
Name: new_row, dtype: float64
"""

# 行をSeriesで追加
df.loc["2020/4/10"] = sr_new
# df.loc["2020/4/10", :] = sr_new と記述してもOK
print(df)
"""
              open     high     low    close
datetime                                    
2020/4/6   108.432  119.393  98.403  109.252
2020/4/7   109.252  119.294  98.680  108.799
2020/4/8     0.000    0.000   0.000    0.000
2020/4/9   108.854  119.071  98.218  108.545
2020/4/10  108.545  118.615  98.341  108.515  <- 追加
"""

ちなみに、Seriesで追加する場合、追加先DataFrameの列数とSeriesのデータ数が一致していなくてもエラーは発生しません。

その代わり、不足分は欠損値NaNで埋められます。

# Seriesデータ作成(2行分のみ)
data = [108.545, 118.615]
index = ["open", "high"]
sr_new2 = pd.Series(data, index, name="new_col")
print(sr_new2)
"""
open    108.545
high    118.615
Name: new_col, dtype: float64
"""

# 行をSeriesで追加(不足分は"NaN"が設定される)
df.loc["2020/4/10-2"] = sr_new2
print(df)
"""
                open     high     low    close
datetime                                      
2020/4/6     108.432  119.393  98.403  109.252
2020/4/7     109.252  119.294  98.680  108.799
2020/4/8       0.000    0.000   0.000    0.000
2020/4/9     108.854  119.071  98.218  108.545
2020/4/10    108.545  118.615  98.341  108.515
2020/4/10-2  108.545  118.615     NaN      NaN  <- 追加
"""

行の結合 [concat()]

pandas.concat()で行方向に結合したい場合は引数にaxis=0を設定します。
(引数axisはデフォルトで”0″なので、axisの省略も可能です。)

結合後のデータは返り値で受け取ります。

以下、"2020/4/8"データをSeriesで作成してDataFrameに結合するサンプルコードになります。

import pandas as pd

# 結合前データ1をDataFrameで作成
ohlc_data = [
    ["2020/4/6", 108.432, 119.393, 98.403, 109.252],
    ["2020/4/7", 109.252, 119.294, 98.680, 108.799],
]
df1 = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high", "low", "close"])
df1.set_index("datetime", inplace=True)
print(df1)
"""
             open     high     low    close
datetime                                   
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
"""

# 結合前データ2をSeriesで作成
data = [108.799, 119.109, 98.514, 108.854]
index = ["open", "high", "low", "close"]
sr1 = pd.Series(data, index, name="2020/4/8")
print(sr1)
"""
open     108.799
high     119.109
low       98.514
close    108.854
Name: 2020/4/8, dtype: float64
"""

# データ1(DataFrame)とデータ2(Series)を行方向に結合
# ※Seriesを行方向に結合するには下記の変換処理が必要です。
#  1.Series -> DataFrame 変換
#  2.DataFrame転置:DataFrame.T
df2 = pd.DataFrame(sr1)
df_c = pd.concat([df1, df2.T], axis=0)
print(df_c)

"""
             open     high     low    close
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
2020/4/8  108.799  119.109  98.514  108.854
"""

pandas.concat()Seriesを行に追加する場合は上記の例を見てもわかるように
 1. Series-> DataFrame変換
 2. DataFrame転置(DataFrame.T)
と、変換の手間がかかります。
なので、Seriesを行に追加したいときは、pandas.concat()ではなく、素直に代入方式を使用した方が良いです。

DataFrame同士を結合することも可能です。

以下、"2020/4/8""2020/4/9"データをDataFrameで作成して元のDataFrameに結合するサンプルコードになります。

import pandas as pd

# 結合前データ1をDataFrameで作成
ohlc_data = [
    ["2020/4/6", 108.432, 119.393, 98.403, 109.252],
    ["2020/4/7", 109.252, 119.294, 98.680, 108.799],
]
df1 = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high", "low", "close"])
df1.set_index("datetime", inplace=True)
print(df1)
"""
             open     high     low    close
datetime                                   
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
"""

# 結合前データ2をDataFrameで作成
ohlc_data = [
    ["2020/4/8", 108.799, 119.109, 98.514, 108.854],
    ["2020/4/9", 108.854, 119.071, 98.218, 108.545],
]
df2 = pd.DataFrame(ohlc_data, columns=["datetime", "open", "high", "low", "close"])
df2.set_index("datetime", inplace=True)
print(df2)
"""
             open     high     low    close
datetime                                   
2020/4/8  108.799  119.109  98.514  108.854
2020/4/9  108.854  119.071  98.218  108.545
"""

# データ1(DataFrame)とデータ2(DataFrame)を行方向に結合
df_c = pd.concat([df1, df2], axis=0)
print(df_c)
"""
             open     high     low    close
datetime                                   
2020/4/6  108.432  119.393  98.403  109.252
2020/4/7  109.252  119.294  98.680  108.799
2020/4/8  108.799  119.109  98.514  108.854
2020/4/9  108.854  119.071  98.218  108.545
"""

参考

スポンサーリンク

コメント

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