LoginSignup
14
16

More than 3 years have passed since last update.

pythonでfor文の中で値の代入更新ができない

Last updated at Posted at 2019-12-06

事の発端

タイトルの通りです。自分があまりにも忘れがちで、やってしまいがちな例なので、備忘のためにメモしておきます。(代入ができないというより、エラーになるが正しいのですが、検索したときに引っかかりやすいと思ったので)
あと、エラーの際の内容もはっきりと理解していないので、アドバイスいただけるとありがたいです。

やりたいことと(追記)

for文の中でdataframeの値の更新。代入というより更新をしたいのです。

動作環境

Windows10
PyCharm
Python3

トラブルの内容

以下のようなfor文をやると変数に値が入らない。
追記)dfの値が更新できない。

import pandas as pd

data = [["勇者", "桃", 1],
        ["動物", "犬", 1],
        ["動物", "猿", 1],
        ["動物", "雉", 1]]

# データフレームの作成
df = pd.DataFrame(data)
# カラム名をdataframeにつける
df.columns = ["job", "name", "level"]
#print(df)

# 間違った例
for i, row in enumerate(df.itertuples()):
    row.level = 2
print(df)

エラーの内容

row.level = 2
AttributeError: can't set attribute
??調べると、プロパティなので、代入できないということ?みたいな?
(・・・まあ、このfor文の中でiとかrowに代入しようとするのもおかしな話ですが、なんというか引数のように見えて代入したくなってしまうのは自分だけではないはず。)

正解のコード

import pandas as pd

data = [["勇者", "桃", 1],
        ["動物", "犬", 1],
        ["動物", "猿", 1],
        ["動物", "雉", 1]]

# データフレームの作成
df = pd.DataFrame(data)
# カラム名をdataframeにつける
df.columns = ["job", "name", "level"]
# print(df)

for i, row in enumerate(df.itertuples()):
    df.iloc[i, 2] = i
print(df)

出力結果(dfの値が更新されている)

job name level
0 勇者 桃 0
1 動物 犬 1
2 動物 猿 2
3 動物 雉 3

追記)以下の方法のほうが良さそうです。

iterrows()とat[]を使う方法

import pandas as pd

data = [["勇者", "桃", 1],
        ["動物", "犬", 1],
        ["動物", "猿", 1],
        ["動物", "雉", 1]]

df = pd.DataFrame(data)                 # データフレームの作成
df.columns = ["job", "name", "level"]   # カラム名をdataFrameにつける

for i, row in df.iterrows():
    df.at[i, 'level'] += i
print(df)

出力結果(dfの値が更新されている)

job name level
0 勇者 桃 1
1 動物 犬 2
2 動物 猿 3
3 動物 雉 4

現在の結論

自分的には、このサイトの記事が参考になったので、ピックアップさせるために引用します。
https://note.nkmk.me/python-pandas-dataframe-for-iteration/
・1行ずつ値を取り出すiterrows()メソッドはビューではなくコピーを返すので、pandas.Seriesを変更しても元データは更新されない。
・at[]で元のDataFrameからデータを選択して処理すると更新される。

あとがき

・dataframeはこのような変更をしようとすると、毎回時間がかかりがちなので、もっと練習が必要ですね。
・より良いコードがあったら更新します。

14
16
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16