Python 如何动态识别列表中的重复模式,然后将其删除?

Python 如何动态识别列表中的重复模式,然后将其删除?,python,string,Python,String,我需要在列表中的字符串中找到重复出现的模式,然后从字符串中删除这些模式 关键是要去除文档标题的网站名称,这样,Amet urna tincidut efficitur-监护人就成了唯一的Amet urna tincidut efficitur 使用正则表达式来实现这一点很简单。但问题是,具体的模式事先并不知道,只是它不断重复 示例数据: data=[“Amet urna tincidunt efficitur-监护人”, “Yltricies hendrerit eu a nisi-卫报”, “

我需要在列表中的字符串中找到重复出现的模式,然后从字符串中删除这些模式

关键是要去除文档标题的网站名称,这样,
Amet urna tincidut efficitur-监护人
就成了唯一的
Amet urna tincidut efficitur

使用正则表达式来实现这一点很简单。但问题是,具体的模式事先并不知道,只是它不断重复

示例数据:

data=[“Amet urna tincidunt efficitur-监护人”,
“Yltricies hendrerit eu a nisi-卫报”,
“Faucibus pharetra id quis arck-守护者”,
“净tristique facilisis |纽约时报”,
“Quis finibus lacinia |纽约时报”,
“我的博客:Net tristique facilisis”,
“我的博客:Quis finibus lacinia”]
我们可以很容易地看到,《卫报》、《纽约时报》和《我的博客》的子串不断重复出现。如何动态识别这些重复出现的模式,然后删除它们

预期产出:

data=[“Amet urna tincidunt efficitur”,
“Yltricies hendrerit eu a nisi”,
“Faucibus pharetra id quis arck”,
“净三色设施”,
“拉齐尼亚之剑”,
“净三色设施”,
“拉齐尼亚之路”]

基本上,您是否希望筛选出一组正确文档中出现最多的单词? 您只需将中的CountVectorizer与所需的切割参数一起使用即可。这是使用max_df参数完成的。根据文档()说明,max_df确定以下内容:

在构建词汇表时,忽略文档频率严格高于给定阈值(特定于语料库的停止词)的术语。

这样,你可以忽略某些频率的单词。那么,只需执行相反的过程,以消除超出所需限制的单词

例如:

from nltk import word_tokenize
from sklearn.feature_extraction.text import CountVectorizer

data = ["Amet urna tincidunt efficitur - The Guardian",
        "Yltricies hendrerit eu a nisi - The Guardian",
        "Faucibus pharetra id quis arck - The Guardian",
        "Net tristique facilisis | New York Times",
        "Quis finibus lacinia | New York Times"]

vectorizer = CountVectorizer(max_df=0.3, lowercase=False, strip_accents=None)
X = vectorizer.fit_transform(data)

vocab = vectorizer.vocabulary_
cv_matrix = X.todense()
new_data = []

for idx_t, text in enumerate(data):
    tokens = word_tokenize(text)
    cv_matrix_ = cv_matrix[idx_t].tolist()[0]
    new_text = []

    for tok_ in tokens:
        if tok_ in vocab.keys():
            new_text.append(tok_)

    new_data.append(" ".join(new_text))
结果:

>>> new_data
['Amet urna tincidunt efficitur',
 'Yltricies hendrerit eu nisi',
 'Faucibus pharetra id quis arck',
 'Net tristique facilisis',
 'Quis finibus lacinia']

您可以迭代地查找常见的模式,并创建最常见模式的列表来删除它们。听起来你有一个足够大的数据集,它不可能100%正确

由于您提到的模式仅出现在开头或结尾,您可以这样做:

从集合导入计数器
数据=[
“Amet urna tincidunt efficitur-卫报”,
“Yltricies hendrerit eu a nisi-卫报”,
“Faucibus pharetra id quis arck-守护者”,
“净tristique facilisis |纽约时报”,
“Quis finibus lacinia |纽约时报”,
“我的博客:Net tristique facilisis”,
“我的博客:Quis finibus lacinia”,
]
def find_common(数据,num_短语=50):
短语=计数器
对于数据中的句子:
对于范围(2,6)内的n:
短语[“”.join(句子.split()[:n])]+=1
短语[“”.join(句子.split()[-n:])]+=1
返回短语。最常用(num\u短语)
查找公用项(数据,8)
出[145]:
[(《卫报》,3),
(“-卫报”,3),
(《纽约时报》,第2期),
('Net tristique facilisis',2),
(《纽约时报》,2),
(《纽约时报》,2),
('Quis finibus lacinia',2),
(“我的博客:”,2)]

从这里,你可以看出,“《卫报》”、“|纽约时报”和“我的博客”是常见的网页名称模式。然后,您可以从数据中删除这些内容,并再次运行它,对其进行迭代,直到您感觉得到了大部分内容。

您需要一个更好的示例。。。如果模式不总是“-”,那么至少应该提供几个不同的模式示例。你至少知道可能的网站名称吗?还是不同的分离器?如果你不知道你将使用哪种类型的分隔符/网站名称,这听起来是一个棘手的问题。这需要通过挖掘您的数据来更好地理解它。谢谢,我添加了更多的示例。挖掘数据当然是一种选择,我的问题是是否有一种方法可以自动完成。一种方法是从你所有的标题中生成N-gram,并创建一个频率图。假设每个网站都有多个条目,您应该开始看到这些条目在顶部冒泡。但是,我认为您必须根据您的发现手动创建一个正则表达式。或者,您可以尝试手动标记一组示例,并尝试使用ML来识别它们,但这似乎很难做到?每个字符串只有一个匹配项?总是有一个分隔符吗?注意:您当前的示例与逻辑不一致。两个字符串“Quis finibus lacinia | New York Times”和“My blog:Quis finibus lacinia”可以简化为“New York Times”和“My blog”,与“Quis finibus lacinia”匹配。@aiguofer是的,这可能有效。虽然决定n-gram使用什么n的复杂性可能会使它相当内存不足,但这绝对是一个好方法。唯一的问题可能是,常见的标题短语可能也会被删除,特别是当有大量网站与标题数量相关时(即,每个网站的文档频率较低)。我想这取决于什么更重要,以确保你不“损害”标题,或确保你删除尽可能多的网站名称模式。然而,这种方法可以更好地生成短语进行研究,因此分析cv_矩阵可以产生相关的模式。我同意,这是一种很好的方法!