首页 > 解决方案 > 函数适用于小样本但不适用于大样本(Python)

问题描述

我正在尝试制作一个函数来查看单词是否出现在彼此之间的一定距离内,我的代码如下:



file_cont = [['man', 'once', 'upon', 'time', 'love', 
'princess'], ['python', 'code', 'cool', 'uses', 'java'],
['man', 'help', 'test', 'weird', 'love']] #words I want to measure 'distance' between

dat = [{ind: val for val, ind in enumerate(el)} for el in file_cont]

def myfunc(w1, w2, dist, dat):
    arr = []
    for x in dat:
        i1 = x.get(w1)
        i2 = x.get(w2)
        if (i1 is not None) and (i2 is not None) and (i2 - i1 <= dist ):    
            arr.append(list(x.keys())[i1:i2+1])
    return arr

它在这种情况下有效,

myfunc("man", "love",4, dat)返回[['man', 'once', 'on', 'time', 'love'], ['man', 'help', 'test' , '奇怪', '爱']]这就是我想要的

我遇到的问题是当我使用更大的数据集(file_cont 的元素变成数千个单词)时,它会输出奇怪的结果

例如,我知道“jon”和“snow”这两个词至少一起出现在 file_cont 的元素之一中

当我做myfunc('jon','snow',6,dat)我得到:

[[], [], ['城堡', '病房'], [], [], []]

完全脱离上下文的东西,它没有提到“乔恩”或“雪”

这里有什么问题,我将如何解决它?

标签: pythonarraysfunctionmemory-managementnlp

解决方案


问题来自这样一个事实,即您的文本可能包含多次出现的同一个单词,您通常会在较大的摘录中观察到。

这是一个最小的工作示例,显示了该功能如何失败:

new_file = [['man', 'once', 'man', 'time', 'love', 'once']]
data = [{ind: val for val, ind in enumerate(el)} for el in new_file]

def myfunc(w1, w2, dist, dat):
    arr = []
    for x in dat:
        i1 = x.get(w1)
        i2 = x.get(w2)
        if (i1 is not None) and (i2 is not None) and (i2 - i1 <= dist ):    
            arr.append(list(x.keys())[i1:i2+1])
    return arr

myfunc("man", "love", 4, data)
# > [['time', 'love']]

请注意,在这里,您的字典将如下所示:

# > [{'man': 2, 'once': 5, 'time': 3, 'love': 4}]

这是因为,在创建字典时,每个新出现的单词都会用新观察到的(更高的)索引替换它在字典中的键。因此,该函数myfunc失败,因为字典中的键不再对应于摘录中单词的索引。


实现您想要做的事情的一种方法可能是(例如):

data = ['man', 'once', 'upon', 'man', 'time', 'love', 'princess', 'man']
w1 = 'man'
w2 = 'love'
dist = 3

def new_func(w1, w2, dist, data):

    w1_indices = [i for i, x in enumerate(data) if x == w1]
    w2_indices = [i for i, x in enumerate(data) if x == w2]

    for i in w1_indices:
        for j in w2_indices:
            if abs(i-j) < dist:
                print(data[min(i, j):max(i, j)+1])
                
new_func(w1, w2, dist, data)
# > ['man', 'time', 'love']
# > ['love', 'princess', 'man']

使用您的情况下的列表列表,您可以执行以下操作:

file_cont = [['man', 'once', 'upon', 'time', 'love', 'princess'], ['python', 'code', 'cool', 'uses', 'java'],
['man', 'help', 'test', 'weird', 'love']]

results = [new_func(w1, w2, dist, x) for x in file_cont]
print(results)
# > ['man', 'once', 'upon', 'time', 'love']
# > ['man', 'help', 'test', 'weird', 'love']

推荐阅读