python - 函数适用于小样本但不适用于大样本(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)我得到:
[[], [], ['城堡', '病房'], [], [], []]
完全脱离上下文的东西,它没有提到“乔恩”或“雪”
这里有什么问题,我将如何解决它?
解决方案
问题来自这样一个事实,即您的文本可能包含多次出现的同一个单词,您通常会在较大的摘录中观察到。
这是一个最小的工作示例,显示了该功能如何失败:
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']
推荐阅读
- python - 使用 Python 从 Azure Speech to Text Services 获取审查词的时间戳
- java - 执行 Pre Handle 方法后未调用 Spring Rest Controller
- swift - 类 --> 结构时 swiftUI+Combine 中的奇怪行为
- c++ - 关于 C++ 中 anagram 相关问题的问题
- java - Java多线程:停止以前的执行并开始新的
- javascript - 给定一组 x 和 y 坐标,在 javascript 中获取曲线方程
- visual-studio - Nuget依赖不成功
- reactjs - 无法从 react-redux 导入“UseSelector”
- python - 如何在 python 中使用 pandas 对多个 DataFrame 执行外部合并
- python - 如何从 C 模块中实例化自定义对象?