【问题标题】:Nested for loops with large data set具有大数据集的嵌套 for 循环
【发布时间】:2015-04-27 23:00:44
【问题描述】:

我有一个子列表列表,每个子列表都包含一个或多个字符串。我将一个子列表中的每个字符串与其他子列表中的每个其他字符串进行比较。这包括编写两个 for 循环。但是,我的数据集是 ~5000 个子列表,这意味着我的程序会一直运行,除非我以 500 个子列表的增量运行代码。如何更改该程序的流程,以便我仍然可以查看与每个 i 对应的所有 j 值,并且能够为约 5000 个子列表运行该程序。 (wn 是 Wordnet 库) 这是我的代码的一部分:

for i in range(len(somelist)):
    if i == len(somelist)-1: #if the last sublist, do not compare
        break
    title_former  = somelist[i]

    for word in title_former:
        singular = wn.morphy(word) #convert to singular
        if singular == None:
            pass 
        elif singular != None:
            newWordSyn  = getNewWordSyn(word,singular)
            if not newWordSyn:
                uncounted_words.append(word)
            else:
                for j in range(i+1,len(somelist)):
                    title_latter = somelist[j]
                    for word1 in title_latter:
                        singular1 = wn.morphy(word1) 
                        if singular1 == None:
                            uncounted_words.append(word1)
                        elif singular1 != None:
                            newWordSyn1      = getNewWordSyn(word1,singular1)
                            tempSimilarity  = newWordSyn.wup_similarity(newWordSyn1)

例子:

Input = [['space', 'invaders'], ['draw']]
Output= {('space','draw'):0.5,('invaders','draw'):0.2}

输出是一个带有对应字符串对元组及其相似度值的字典。上面的代码sn -p 是不完整的。

【问题讨论】:

  • 你能给我们一个小例子输入和预期输出
  • 现在我明白你在做什么了......嗯......这可能很慢......
  • 如果它很慢就可以了,但它几乎无法运行:(

标签: python for-loop nested large-data


【解决方案1】:

做一些预处理而不是一遍又一遍地做一堆操作怎么样?我没有对此进行测试,但您明白了;你需要尽你所能。

# Preprocessing:
unencountered_words = []
preprocessed_somelist = []
for sublist in somelist:
    new_sublist = []
    preprocessed_somelist.append(new_sublist)
    for word in sublist:
        temp = wn.morphy(word)
        if temp:
            new_sublist.append(temp)
        else:
            unencountered_words.append(word)

# Nested loops:
for i in range(len(preprocessed_somelist) - 1): #equivalent to your logic
    for word in preprocessed_somelist[i]:
            for j in range(i+1, len(preprocessed_somelist)):
                   for word1 in preprocessed_somelist[j]:
                            tempSimilarity  = newWordSyn.wup_similarity(newWordSyn1)

【讨论】:

  • 谢谢,我会调查一下,看看有没有什么不同。
【解决方案2】:

您可以尝试这样的方法,但我怀疑它会更快(并且您可能需要更改距离函数)

    def dist(s1,s2):
        return sum([i!=j for i,j in zip(s1,s2)]) + abs(len(s1)-len(s2))

    dict([((k,v),dist(k,v)) for k,v in itertools.product(Input1,Input2)]

【讨论】:

  • 哎呀少了一个括号
  • 嗯,我不确定如何将我的代码翻译成这个。距离是指字符串之间的相似度吗?
  • 是的,看起来您正在使用一些库函数newWordSyn.wup_similarity(newWordSyn1),但我对该库一无所知,所以我不确定它在做什么或计算需要多长时间......
  • 是的,但我不是主要问题,因为我嵌套了 for 循环和庞大的数据集,不一定是库方法?
  • 你可以用python -m cprofile myscript.py对其进行分析,然后在runsnakerun中查看输出
【解决方案3】:

这总是会出现缩放问题,因为您正在进行 n^2 字符串比较。 Julius 的优化当然是一个很好的起点。

接下来您可以存储相似度结果,这样您就不必重复比较相同的词。

您可以进行的另一项优化是存储单词的比较,并在遇到相同的单词时重复使用它们。

key = (newWordSyn, newWordSyn1)
if key in prevCompared:
    tempSimilarity  = prevCompared[(word, word1)]
else:
    tempSimilarity  = newWordSyn.wup_similarity(newWordSyn1)
    prevCompared[key] = tempSimilarity
    prevCompared[(newWordSyn1, newWordSyn)] = tempSimilarity

这仅在您会看到很多相同的单词组合时才有帮助,但我认为 wup_similarity 非常昂贵。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 1970-01-01
    • 2019-12-17
    • 2018-09-30
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多