假设您在数据框 df 中有一个名为 Text 的列,您可以尝试以下操作:
df2 = df['Text'].str.split().explode()
m = df2.str.contains(r'[A-Za-z]') & df2.str.contains(r'\d')
df_out = df2[~m].groupby(level=0).agg(' '.join)
df_out = df_out.to_frame(name='Text')
解释
我们将文本分成单独的单词,然后将单词列表拆分成多行,每行一个单词。然后,我们使用正则表达式通过.str.contains()
测试单词是否包含任何字母和数字。
.str.contains(r'[A-Za-z]') # test any character in [A-Za-z] in string
并且
.str.contains(r'\d') # test any numeric digit in string
然后,通过alpha和digit测试的布尔掩码,我们仅选择不包含
同时包含字母和数字的行条目:
df2[~m]
然后,我们通过使用工具将过滤后的单词(不包括字母数字)重新组合成句子。
groupby(level=0).agg(' '.join)
在这里,我们按
level=0
进行分组,这是在展开之前的原始行索引(即原始行号)。
演示
data = {'Text': ['2fvRE-Ku89lkRVJ44QQFN ABACUS LABS, INC', 'abc123 CAT LABS, INC']}
df = pd.DataFrame(data)
Text
0 2fvRE-Ku89lkRVJ44QQFN ABACUS LABS, INC
1 abc123 CAT LABS, INC
df2 = df['Text'].str.split().explode()
m = df2.str.contains(r'[A-Za-z]') & df2.str.contains(r'\d')
df_out = df2[~m].groupby(level=0).agg(' '.join)
df_out = df_out.to_frame(name='Text')
Text
0 ABACUS LABS, INC
1 CAT LABS, INC
编辑
我们也可以简化为:
df2 = df['Text'].str.findall(r'\b(?!.*[A-Za-z]+.*\d+)(?!.*\d+.*[A-Za-z]+.*).+\b').str.join(' ').str.strip()
解释
这里我们使用的正则表达式仍然符合排除字母数字单词的要求。正则表达式:
r'\b(?!.*[A-Za-z]+.*\d+)(?!.*\d+.*[A-Za-z]+.*).+\b'
在单词边界
\b
....
\b
内,我们使用两个负向先行断言来检查
同时包含字母和数字字符。我们需要两个负向先行断言而不是一个,因为字母可能出现在数字之前或者反过来。