文字列を比較し、データフレームレコードが1回一致した場合は、次の行に進みます

Dec 04 2020

私はそのようなデータフレームを持っています:

df = pd.DataFrame({'item_descrip': ['ebc root beer single', 
                                    'yic yac big pack freshmint', 
                                    'froggy jumbo flakes',
                                    'jumbo tart warmer',
                                    'beer jerky'
                                   ]
})

私はそのようなリストを持っています:

brand_list = ['ebc', 'yic yac', 'beer', 'jumbo', 'tart', 'froggy']

brand_listの文字列を列の文字列にitem_descrip一致させ、item_descrip列の一致を削除したいと思います。unbrandedからクリーンアップされた文字列を含む別の列を作成したいと思いますitem_descrip

私の問題は、私が非常に大きくbrand_list、このリストの文字列の一部が列内で複数回一致していることitem_descripです。私の希望する出力は、1つの行に一致するものがすでに見つかっている場合は、その行をスキップすることです。

必要な出力:

|    | item_descrip                       | unbranded                          |
|---:|:-----------------------------------|:-----------------------------------|
|  0 | ebc root beer single               | root beer single                   |
|  1 | yic yac big pack freshmint singles | big pack freshmint singles         |
|  2 | froggy jumbo flakes                | jumbo flakes                       |
|  3 | jumbo tart warmer                  | tart warmer                        |
|  4 | beer jerky                         | jerky                              |

これは一致を削除するために機能するコードですが、item_descrip列内のすべての一致を削除します。例えば、私の中でbrand_list私が持っているebcbeer、リストインチ 最初のレコードでは、すでに一致が行われているため、ebc削除したいだけですbeer。文字列の最初の部分で一致が見つかった場合は、そのレコードをそれ以上処理せずに、次の部分に進みます。

したがって、基本的には、ifステートメントがリスト内包表記に入る可能性があるように見えますが、次のような記述方法がわかりません。一致したパスの場合、それ以外の場合は検索を続けます。

df['unbranded'] = [' '.join([y for y in x.split() if not y.startswith(tuple(brand_list))]) for x in df['item_descrip']] 

私はここでこのワンライナーを最大限に活用しました: https://stackoverflow.com/questions/51666374/how-to-remove-strings-present-in-a-list-from-a-column-in-pandas

回答

1 DaniMesejo Dec 04 2020 at 23:10

免責事項私はtrrexの作者です

パフォーマンスが気になる場合は、trrexを使用してください。

import pandas as pd
import trrex as tx

df = pd.DataFrame({'item_descrip': ['ebc root beer single',
                                    'yic yac big pack freshmint',
                                    'froggy jumbo flakes',
                                    'jumbo tart warmer',
                                    'beer jerky'
                                    ]
                   })

brand_list = ['ebc', 'yic yac', 'beer', 'jumbo', 'tart', 'froggy']

df['unbranded'] = df['item_descrip'].str.replace(tx.make(brand_list), '', n=1)
print(df)

出力

                 item_descrip            unbranded
0        ebc root beer single     root beer single
1  yic yac big pack freshmint   big pack freshmint
2         froggy jumbo flakes         jumbo flakes
3           jumbo tart warmer          tart warmer
4                  beer jerky                jerky

関数makeは、トライ正規表現を作成します。何が起こっているのかをよりよく理解するために、makeは次の正規表現生成します。

\b(?:froggy|tart|beer|yic yac|jumbo|ebc)\b

引数n = 1は、ドキュメントから、パターンが1回だけ置き換えられることを意味します。

n int、デフォルト-1(すべて)

Number of replacements to make from start.