

下記のように、URLを格納したデータフレームがあります。  
こちらに、特定のパラメータの値を抽出し、新しい列を作って代入したいと考えています。

[code]

    df = pd.DataFrame({'ulr' : ['https://www.shop.jp/shop/pro_source=google&pro_md=list_1&pro_cp=sweets_&gclid=?skejsurieksoduuuuis23028', 'https://www.shop.jp/shop/pro_source=yahoo&pro_cp=sweets_&pro_md=list_2&pro_cm=gclid=?skejsurieksoduuuuis23028',
    'None', 'https://www.shop.jp/shop/pro_source=&pro_md=&pro_cp=sweets_&gclid=?skejsurieksoduuuuis23028', 'https://www.shop.jp/shop/pro_source=google&pro_md=list_1&pro_cp=sweets_&gclid=?skejsurieksoduuuuis23028']})
    
[/code]

具体的には、下記を実現したいです。

pro_source というパラメータについては、その値を抽出し「source」という列を作成して格納  
pro_md というパラメータについては、その値を抽出し「md」という列を作成して格納

出来上がるデータフレームイメージは以下です。

[code]

    ans = pd.DataFrame({'ulr' : ['https://www.shop.jp/shop/pro_source=google&pro_md=list_1&pro_cp=sweets_&gclid=?skejsurieksoduuuuis23028', 'https://www.shop.jp/shop/pro_source=yahoo&pro_cp=sweets_&pro_md=list_2&pro_cm=gclid=?skejsurieksoduuuuis23028',
    'None', 'https://www.shop.jp/shop/pro_source=&pro_md=&pro_cp=sweets_&gclid=?skejsurieksoduuuuis23028', 'https://www.shop.jp/shop/pro_source=google&pro_md=list_1&pro_cp=sweets_&gclid=?skejsurieksoduuuuis23028'],
                        'source': ['google', 'yahoo', '入力なし', '', 'google'],
                        'md': ['list_1', 'list_2', '入力なし', '', 'list_1']})
    
[/code]

これを実現するために、以下の記述をしてみたところ、上記のサンプルデータフレームに対しては、想定の結果を得ることができたのですが、実際にフラグを立てたいデータ（レコード数1000万件程のデータ）に適用してみたところ、「エラー：list
index out of range」というエラーが出てしまいました。

[code]

    import re 
    
    def get_source(x):
        if  x == 'None':
            return '入力なし' 
        elif 'pro_source=' in x:
            return re.findall('pro_source=(.*?)&pro_', x)[0]
        else:
            return 'その他'
    
    def get_md(x):
        if  x == 'None':
            return '入力なし' 
        elif 'pro_md=' in x:
            return re.findall('pro_md=(.*?)&pro_', x)[0]
        else:
            return 'その他'
    
    df['source'] = df['ulr'].apply(get_source)
    df['md'] = df['ulr'].apply(get_md)
    
[/code]

上記サンプルコードではエラーが出ずに実行できていたので、プログラム自体は問題がない認識なのですが、エラーが起こってしまう理由（適用したいデータに想定される事象）と、回避方法がありましたらアドバイスいただけますと幸いです。


CC BY-SA 4.0
2020-10-05T10:56:49.823
70936
2021-01-30T13:46:07.623
2020-10-05T11:39:15.530
3060
41758
question
python pandas 正規表現
Python の正規表現で特定の文字列を抽出する関数の定義


データを見てみないと詳しくはわかりませんが，後ろに&pro_がついていないデータがあるのではないでしょうか。その場合，inの検査で存在を確認してからfindallをしても，後ろの文字列を見つけられずに，findall自体が空のリストを返すので，空リストの要素を取り出そうとしたときにエラーとなっているのではないかと思います。  
取り出す範囲の終わりを示す文字列を&だけにしてみてはいかがでしょう。

[code]

    return re.findall('pro_source=(.*?)&', x)[0]
    
[/code]

または，必ず末尾を見つけられるように文字列の後ろに追加してもよいかもしれません。

[code]

    return re.findall('pro_source=(.*?)&pro_', x + '&pro_')[0]
    
[/code]

この方法であれば，後ろに&がなくても（行末であっても）必ず見つけてくれると思います。


CC BY-SA 4.0
2021-01-30T13:46:07.623
73705
2021-01-30T13:46:07.623
43754
70936
answer