70244


pandasのデータフレームで変換するためのプログラムを書こうと試みていますが、うまくいきません。

masterという名前のデータフレームにidごとにどの変数をどう上書きするか、の対応が入っています。

[code]

    id,上書き列名,上書き文字列
    1,x2,ああああ
    2,x4,いいい
    
[/code]

dfというデータフレームをmasterの対応を用いて変換したいです。  
（ちなみにdfの全サンプルを変換するのではなく、masterに乗っているidのみを変換します。  
＝len(df)>len(master)  
また、masterのidは重複の可能性があります。  
＝1つのidに対してx2とx54に対する変換が生じる可能性がある。）  
以下がdfの例です。

[code]

    id,x1,x2,...,x345
    1,あいう,かかか, ...,きくけ,
    
[/code]

dfを以下のようなif文を使って書き換えたいです。  
（masterテーブルに習い、id=1のときはx2をああああに、id=2のときはx4をいいいに、という感じです。）

[code]

    if id == master.id:
        df.x1 = df.x1.上書き文字列
    
[/code]

変換する変数と書き込む文字列、のように組が二つだと辞書が使えるのですが、3つの変数(id、上書き変数名、上書き文字列)が必要なので辞書が使えない状況です。  
（辞書が使えればfor i,j in items()でループさせられる。）  
リストで3つごとにループさせるくらいしか思いつかないですが、他に良い方法はありますでしょうか。  
よろしくお願いいたします。


CC BY-SA 4.0
2020-09-08T16:43:11.197
70234
2020-09-09T07:52:19.737
2020-09-09T07:52:19.737
754
12457
question
python pandas
pandas における index 番号と対象列を別データフレームとして指定してのデータフレーム変換


[`to_dict`](https://pandas.pydata.org/pandas-
docs/stable/reference/api/pandas.DataFrame.to_dict.html)で辞書型にキャストすると値も辞書型になるので、辞書の値から必要な組を取得することでループを増やさずに済むのではないでしょうか。

**サンプルコード**

[code]

    from pandas import Series, DataFrame
    import pandas as pd
    
    master = DataFrame({'id':[1, 2], '上書き列名': ['x2', 'x4'], '上書き文字列': ['ああああ', 'いいい']})
    df = DataFrame({'id':[1, 2], 'x1': ['あ', 'あ'], 'x2': ['い', 'い'], 'x3': ['う', 'う'], 'x4': ['え', 'え']})
    
    dict = master.set_index('id').to_dict('index')
    print(dict)
    
    for id in dict:
        value = dict[id]
        df.loc[df['id'] == id, value['上書き列名']] = value['上書き文字列']
    
    print(df)
    
[/code]

**出力結果**

[code]

    {1: {'上書き列名': 'x2', '上書き文字列': 'ああああ'}, 2: {'上書き列名': 'x4', '上書き文字列': 'いいい'}}
       id x1    x2 x3   x4
    0   1  あ  ああああ  う    え
    1   2  あ     い  う  いいい
    
[/code]


CC BY-SA 4.0
2020-09-09T00:31:09.867
70240
2020-09-09T00:31:09.867
9820
70234
answer


データフレーム `master` を `id` と `上書き列名` でグループ化して pivot します。その後、pivot した `master`
データフレームで `df` を更新(`pandas.DataFrame.update()`)します。

[code]

    import pandas as pd
    pd.set_option('display.unicode.east_asian_width', True)
    
    master = pd.DataFrame({
      'id': [1, 2, 2, 1],
      '上書き列名': ['x2', 'x4', 'x6', 'x1'],
      '上書き文字列': ['ああああ', 'いいい', 'ううううう', 'んん']
    })
    
    df = pd.DataFrame({
      'id': [1, 2],
      'x1': ['あ', 'あ'],
      'x2': ['い', 'い'],
      'x3': ['う', 'う'],
      'x4': ['え', 'え'],
      'x5': ['お', 'お'],
      'x6': ['か', 'き'],
    })
    
    print(master)
    #    id 上書き列名 上書き文字列
    # 0   1       x2     ああああ
    # 1   2       x4      いいい
    # 2   2       x6   ううううう
    # 3   1       x1        んん
    
    print(df)
    #    id  x1  x2  x3  x4  x5  x6
    # 0   1  あ   い  う  え   お  か
    # 1   2  あ   い  う  え   お  き
    
    df.update(
      master.groupby(['id', '上書き列名'])['上書き文字列']
      .first().unstack().reset_index()
    )
    
    print(df)
    #    id    x1       x2  x3    x4   x5       x6
    # 0   1   んん  ああああ  う     え   お        か
    # 1   2     あ       い  う  いいい  お  ううううう
    
[/code]


CC BY-SA 4.0
2020-09-09T03:03:23.767
70244
2020-09-09T03:13:26.773
2020-09-09T03:13:26.773
70234
answer