Python

pandasでindexが一致した列の値を一括更新する方法

2019-08-25

pandasでindexが一致した列の値を一括更新する方法

pandasのDataFrameを2つ用意して、indexが一致した列の値をもう片方の列の値で一括更新する方法って無いですかね


表形式のデータを扱うのに便利なpandas.DataFrame

pandasのDataFrameを複数扱っていると、ときにはpandasで元のDataFrameと作業用のDataFrameを用意して、作業用のDataFrameで得られた値を元のDataFrameのindexが一致する行に反映したい場合があるだろう。

そこで今回はpandasでindexが一致した列の値を一括更新する方法について紹介する。

この記事を書いている人


システムエンジニア、AIエンジニアと、IT業界で10年以上働いている中堅。PythonとSQLが得意。

記事を読むメリット

pandasでindexが一致した列の値を一括更新する方法がわかり、pandasでのデータ更新が得意になる


pandasでindexが一致した列の値を一括更新したいケース

pandasでindexが一致した列の値を一括更新したいケースのひとつとして、機械学習の予測結果列の反映がある。

機械学習時に学習用のデータとして、説明変数Xと目的変数yが含まれたデータがあり、そこに予測結果用のカラムを追加する。

今回はその流れを例として解説する。


準備

まずは機械学習を想定して、元データを学習用と予測用に分割してそれぞれに予測結果列を追加し、予測結果を元データに反映する流れを見ていこう。



データを用意

まずは解説用のデータを用意する。

# Initialize
import pandas as pd
import numpy as np

cols = ["x1", "x2", "y"]
vals = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
df = pd.DataFrame(vals, columns=cols)
print(df)

#    x1  x2   y
# 0   1   2   3
# 1   4   5   6
# 2   7   8   9
# 3  10  11  12

print()



データ分割

機械学習のケースを想定してデータを学習用とテスト用に分ける。

# split data
df_train, df_test = df.iloc[0:-2], df.iloc[-2:]
print(df_train)
#    x1  x2  y
# 0   1   2  3
# 1   4   5  6

print(df_test)
#    x1  x2   y
# 2   7   8   9
# 3  10  11  12

print()



カラム追加

機械学習の工程は今回の主題ではないので省き、予測結果を想定したカラムを追加する。

# add new column
y_pred_train = [3.1, 6.2]
df_train = df_train.assign(y_pred = y_pred_train)
y_pred_test = [9.3, 12.4]
df_test = df_test.assign(y_pred = y_pred_test)

print(df_train)
#    x1  x2  y  y_pred
# 0   1   2  3     3.1
# 1   4   5  6     6.2

print(df_test)
#    x1  x2   y  y_pred
# 2   7   8   9     9.3
# 3  10  11  12    12.4

print()


この予測結果を y_pred 列を持たない元データ df に反映したい。



元データに反映

機械学習での予測結果を元のDataFrameに反映する。
ここでは間違いやすい例を含めて3つ紹介する。


代入

DataFrameのカラムを指定して代入する方法がある。
しかしこの方法は代入したいデータ、この例でいうと予測結果を持つDataFrameがひとつの場合のみ成立する。
この例のように元のDataFrame df に 学習データ df_train と テストデータ df_test という2つのデータを反映したい場合では、後から上書きした方でindexがマッチしないものまで NaN で上書きされてしまう

# concat split data to original (Override)
df1 = df.copy()
df1["y_pred"] = df_train["y_pred"]
df1["y_pred"] = df_test["y_pred"]
print(df1)

#    x1  x2   y  y_pred
# 0   1   2   3     NaN
# 1   4   5   6     NaN
# 2   7   8   9     9.3
# 3  10  11  12    12.4

print()



Update

DataFrameの update メソッドを使う方法もある。
しかしデータを追加したい元のDataFrame df に追加したいカラムが無いと反映されない。

# concat split data to original (Lack of column)
df2 = df.copy()
df2.update(df_train)
df2.update(df_test)
print(df2)

#      x1    x2     y
# 0   1.0   2.0   3.0
# 1   4.0   5.0   6.0
# 2   7.0   8.0   9.0
# 3  10.0  11.0  12.0

print()


y_pred 列が無いね



カラム追加してupdate

カラムを追加してからupdateすると、学習データ df_train と テストデータ df_test の両方の予測結果を反映できる。

# concat split data to original (Update)
df3 = df.copy()
df3["y_pred"] = None
df3.update(df_train)
df3.update(df_test)
print(df3)

#      x1    x2     y y_pred
# 0   1.0   2.0   3.0    3.1
# 1   4.0   5.0   6.0    6.2
# 2   7.0   8.0   9.0    9.3
# 3  10.0  11.0  12.0   12.4

print()


y_pred が全部の行に反映できた!



まとめ

今回はpandasでindexが一致した列の値を一括更新する方法について紹介した。

pandasでindexが一致した列の値を一括更新するには update を使う。

ただし更新したいカラムが元データに無ければ更新できないのでそこでけ注意したい。



他にもpandas関連の記事もあるので、もし気になるものがあれば見てみて欲しい

ITipsと同じようなブログを作る方法

ブログに興味がありますか?

もしブログに興味がある場合は↓このページ↓を参考にすれば、ITipsと同じ構成でブログを作ることができます

サーバー、ドメイン、ASPと【ブログに必要なものは全て】このページに書きました。
同じ構成でブログ作るのはいいけど、記事はマネしないでネ (TДT;)

ランキング参加中

にほんブログ村 IT技術ブログへ

他にもブログやSNSで紹介してくれると励みになります。

はてブのコメントで酷評されると泣きます(´;ω;`)

-Python
-,

© 2024 ITips