首先 - 标题很乱,但我想不出更好的标题。
我有一个问题,我确信存在一个简单的解决方案,但我现在无法想到一个。
我有一个像这样的数据框。我将这个数据框称为“A”。 x 和 y 的编号没有系统,我只是添加它们以表明可以重复。
猫0 | 猫1 | 猫2 |
---|---|---|
x0 | 两个 | y0 |
x1 | 七 | y1 |
x2 | 八 | y2 |
x3 | 八 | y2 |
x4 | 十二 | y7 |
然后,我使用以下函数,使用 max 读出 cat1 中哪个单词在文本中最常见。这就是我的主题。我这样做了几千条文本,每条文本都是从 pdf 第一页读出的。
def subject_findall(string):
matches = []
txt = re.sub(r"[^nA-Za-z-ÖØ-öø-ÿ+]+", "", string).lower()
txt = re.sub(r"\d", "", txt)
for i in range(0, len(A)):
searchfor = re.sub(r"[^nA-Za-z-ÖØ-öø-ÿ+]+", "", A["cat1"][i]).lower()
match = re.findall(searchfor, txt)
matches.extend(match)
if len(matches) > 0:
subject = max(matches, key = lambda x: matches.count(x))
else:
subject = r"nosubjectfound"
print(subject)
return subject
这将返回最常见的主题。但我还需要有关正确主题的 cat0 和 cat2 的信息。如果函数返回 (subject, cat0ofsubject, cat2 ofsubject) 的元组,那就最好了。
有什么方法可以存储带有“searchfor”术语的行索引吗?我尝试过使用元组(cat1,索引)。但是用我构建函数的方式来迭代这是不可能的,我需要迭代列表中每个元组的每个第一个元组项。第二个想法是获取值,然后再次搜索 A,找到正确的行并从中检索所需的信息。我想避免这种情况,因为它会使我的缓慢代码变得更慢。
第三个选择是不在函数之外解决这个问题:我可以创建一个仅包含匹配项的 df,然后基于 cat1,将 cat0 和 cat2 合并到该 df 上。这带来了另一个问题:这将创建重复项,因为 cat1 不是唯一的。所有其他变量也不是唯一的,因此如果我删除重复项,我将不可避免地删除不应删除的项目。
我希望我能够充分描述问题。如果我写的有什么不清楚的地方请询问。
KR
如果我理解正确,并且假设您没有寻找重叠的单词,则可以大大简化逻辑以避免循环所有值。
Counter
来计数并找到最常见的:
import re
from collections import Counter
def subject_findall(string, df=A):
s = df['cat1'].str.replace(r"[^nA-Za-z-ÖØ-öø-ÿ+]+", "", regex=True).str.lower()
words = set(s)
regex = '|'.join(map(re.escape, words))
counts = Counter(re.findall(regex, string.lower()))
if not counts:
print('nosubjectfound')
else:
top = c.most_common(1)[0][0]
print(f'most common: {top}')
return df[s.eq(top)]
text = 'This is an example with Seven Two Seven and Eight.'
subject_findall(text)
打印:
most common: seven
输出:
cat0 cat1 cat2
1 x1 Seven y1