首页 > 解决方案 > 比较字符串,如果数据帧记录匹配一次,则继续到下一行

问题描述

我有一个像这样的数据框:

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。我想要的输出是如果已经为某一行找到匹配项,则跳过该行。

期望的输出:

|    | 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

标签: pythonpandas

解决方案


免责声明:我是 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 将构建一个trie 正则表达式。为了更好地理解正在发生的事情,make生成以下正则表达式:

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

参数 n=1,意味着模式只会被替换一次,来自文档

n int,默认 -1(全部)

Number of replacements to make from start.

推荐阅读