54256


こちらに質問させていただいた、  
[python pandas
2つのcsvの共通の列の値を使って結合したい](https://ja.stackoverflow.com/questions/42564/python-
pandas-2%E3%81%A4%E3%81%AEcsv%E3%81%AE%E5%85%B1%E9%80%9A%E3%81%AE%E5%88%97%E3%81%AE%E5%80%A4%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E7%B5%90%E5%90%88%E3%81%97%E3%81%9F%E3%81%84)  
で、データフレームの結合が出来ました、ありがとうございます。  
この結合されたデータフレームに対して、文字列の検索と置き換えがしたいです。

前の質問の続きなので使いまわしていますが、今回の質問ではidとvalueは考慮しなくて良いのでここでは非表示としました。  
ただし、データとしては存在しますので、最終的な結果としてこれらも取得できる状態であることが前提です。

[code]

    [df]
    param1
    Value-1
    VAlue-2
    dF3-3
    NAN
    Value-1
    dF3-1
    ...
    
[/code]

に対し、文字列置き換え専用のルールを書いてあるreplace_csvを使って内容を置き換えます。  
replace_csvをデータフレームに直すと、以下のような内容が得られます。

[code]

    replace_df = pd.read_csv('replace_csv')
    [replace_df]
    target, param2
    *-1, replace-A
    *-2, replace-B
    ...
    
[/code]

期待する結果

[code]

    [new_df]
    param1,param2
    Value-1,replace-A
    VAlue-2,replace-B
    dF3-3,NaN
    NAN,NaN
    Value-1,replace-A
    dF3-1,replace-A
    
[/code]

[実装イメージ]

[code]

    # df['param2']にreplace_df.targetのルールに対応したreplace_df.param2を入れたい
    df['param2'] = replace_df[df.param1.str.contains(replace_df.target)].param2
    
[/code]

このコードだと当然エラーになりますが、やりたい事のニュアンスが伝われば幸いです。

なお、replace_csvのtargetは自分で作っているので、正規表現を使わない方法で実装出来れば`*`を外すこともできます。  
が、replace_csvがどういう役割を持っているのか見えた方がいいと思うので、できれば`*`はつけておきたいです。（カッコはアスタリスクが見えなくなるので表示のため使用）  
この場合、どのように実装するのが良いでしょうか？

先の質問と同じくfor ～ sqldfを使わない方法を考えたいです。


CC BY-SA 3.0
2018-03-22T07:45:13.760
42571
2020-04-08T17:02:00.247
2018-03-22T10:15:10.100
19110
27817
question
python pandas
データフレームの文字列を正規表現で、該当した行の列をmergeしたい

[code]

    >>> print(df)
        param1
    0  Value-1
    1  VAlue-2
    2    dF3-3
    3      NAN
    4  Value-1
    5    dF3-1
    
    >>> print(replace_df)
      target     param2
    0   .*-1  replace-A
    1   .*-2  replace-B
    
[/code]

上記のような df たちがあったとき、

[code]

    df.assign(**{
      s['param2']: df.param1.str.contains(s['target'])
      for s in replace_df.to_dict(orient='records')
    }).set_index('param1').pipe(
      lambda df:
      df.assign(
        param2=df[df].T.apply(
          lambda inner:
          inner.first_valid_index()
        )
      )['param2'].reset_index()
    )
    
[/code]

を評価すると、

[code]

        param1     param2
    0  Value-1  replace-A
    1  VAlue-2  replace-B
    2    dF3-3       None
    3      NAN       None
    4  Value-1  replace-A
    5    dF3-1  replace-A
    
[/code]

になることは確認しました。割と、力技しかないんじゃないかな、と思っています。

* * *

全文

[code]

    import pandas as pd
    import numpy as np
    
    d = [
    'Value-1',
    'VAlue-2',
    'dF3-3',
    'NAN',
    'Value-1',
    'dF3-1'
    ]
    
    df = pd.Series(d).to_frame('param1')
    print(df)
    
    replace_df = pd.DataFrame({
        'target': ['.*-1', '.*-2'],
        'param2': ['replace-A', 'replace-B']
    })
    print(replace_df)
    
    result_df = df.assign(**{
        s['param2']: df.param1.str.contains(s['target'])
        for s in replace_df.to_dict(orient='records')
    }).set_index('param1').pipe(
        lambda df:
        df.assign(
            param2=df[df].T.apply(
                lambda inner:
                inner.first_valid_index()
            )
        )['param2'].reset_index()
    )
    
    print(result_df)
    
[/code]


CC BY-SA 4.0
2019-04-17T10:57:42.990
54256
2019-04-17T10:57:42.990
754
42571
answer