Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用python搜索大型文本文件是否包含句子中的单词?_Python_Pandas_Search_Lemmatization - Fatal编程技术网

如何使用python搜索大型文本文件是否包含句子中的单词?

如何使用python搜索大型文本文件是否包含句子中的单词?,python,pandas,search,lemmatization,Python,Pandas,Search,Lemmatization,我有一个包含单词的文本文件,它们的每一行在第一列包含单词形式,在第二列包含单词引理 我有一个tweet(句子)列表,我需要将其转换为单词引理-每个单词都需要转换为它们的引理(文本文件的第二列) 我试着打开和关闭每个单词的文本文件,但这太长了(每个单词在文本文件中找到引理大约需要15秒)。函数如下所示 def returnLemma(str): str= word_tokenize(str) end_str = "" for word in str: inf

我有一个包含单词的文本文件,它们的每一行在第一列包含单词形式,在第二列包含单词引理

我有一个tweet(句子)列表,我需要将其转换为单词引理-每个单词都需要转换为它们的引理(文本文件的第二列)

我试着打开和关闭每个单词的文本文件,但这太长了(每个单词在文本文件中找到引理大约需要15秒)。函数如下所示

def returnLemma(str):
    str= word_tokenize(str)
    end_str = ""
    for word in str:
        infile = open('MorphDict.txt', 'r')
        for line in infile:
            line.strip()
            prva=line.split()[0] 
            druga=line.split()[1]
            if word==prva:
                end_str = end_str+" "+druga 
                break;
        infile.close()
    return end_str

是否可以更高效地搜索此文本文件(>100MB)?有没有可能用这个来解决这个问题?

当您需要比较两个列表的元素时,其中一个比另一个小得多,请使用内部循环中最小的元素。这将永远是更有效的

尽量不要做同样的工作两次。当你分开生产线时,保留零件,这样你就不需要再做了

line.strip()
不会更改
line
,而是生成一个不带空格的新行。使用
line=line.strip()


您可以从头开始查找,而不是重复打开文件。

我将编写如下相同的函数:

from collections import defaultdict


word_tokenize = lambda s: s.split()


def returnLemma(s, morph_lines):
    tokens = word_tokenize(s)
    token_positions = defaultdict(list)
    for i, t in enumerate(tokens):
        token_positions[t].append(i)

    drugas = [None] * len(tokens)
    for line in morph_lines:
        line = line.strip()
        parts = line.split(maxsplit=3)
        prva = parts[0]
        try:
            positions = token_positions[prva]
        except KeyError:
            pass
        else:
            druga = parts[1]
            for i in positions:
                drugas[i] = druga

    return ' ' + ' '.join(
        druga if druga is not None else token
        for token, druga in zip(tokens, drugas)
    )


import unittest


class ReturnLemmaTest(unittest.TestCase):

    def test_when_nothing_matches_then_it_returns_a_single_space(self):
        result = returnLemma('hello world', ['line 1', 'line 2'])
        self.assertEqual(' hello world', result)

    def test_when_one_line_matches_then_it_returns_its_second_word(self):
        result = returnLemma('hello world line-b', ['line-a 1', 'line-b 2'])
        self.assertEqual(' hello world 2', result)

    def test_when_many_lines_match_then_it_returns_their_second_words_separated_by_a_space(self):
        result = returnLemma('hello b world b c', ['a 0', 'b 1', 'c 2'])
        self.assertEqual(' hello 1 world 1 2', result)


if __name__ == '__main__':
    unittest.main()

returnLemma
的第二个参数可以是一个打开的文件,但它更容易用列表进行测试。

这是最终的工作代码,只需对od@Javier的函数做一些小的更改。感谢大家的帮助,特别是@Javier和@MaxU

from nltk.tokenize import word_tokenize
from collections import defaultdict

def vratiLemu(s, morph_lines):
    tokens = word_tokenize(s)
    token_positions = defaultdict(list)
    for i, t in enumerate(tokens):
        token_positions[t].append(i)

    for line in morph_lines:
        line = line.strip()
        parts = line.split()
        prva = parts[0]
        try:
            positions = token_positions[prva]
        except KeyError:
            pass
        else:
            druga = parts[1]
            for i in positions:
                tokens[i] = druga

    return ' ' + ' '.join(druga for druga in tokens if druga is not None)              

morphDict= open('SveSrpMDANSI.txt', 'r')
out=vratiLemu1("Suštinsko pitanje nije postavljeno: zašto predsednik odbora nije otvorio pretres a morao je",morphDict)
print out

Suštinsko pitanje jesam postavljen:zašto predsednik odbor jesam otvoriti pretres a morati jeste

你的两个问题的答案基本上都是肯定的。但是,您可能会考虑重构此代码,以便从代码> > MyDist.txt>代码>中读取数据,并将其作为函数传递给函数(一次)。旁注:您当前使用
str
作为名称,这与Python内置的名称冲突。您可以发布一个小的可复制输入数据集和所需的数据集吗?你在问什么语言?这是英文文本吗?你为什么要在这里使用熊猫?@Javier为什么不?您可以将字符串串联在一个字符串中command@roganjosh乍一看,这似乎是一个非常简单的函数。加入熊猫会让事情变得更复杂。我可能不明白你的意思。列表可以用来保存要连接的字符串,因此连接起来比在post中更有效。如果您使用熊猫发布此代码,可能会澄清我的误解。@roganjosh这是我在不将整个文件加载到内存的情况下所能做的最好的事情。抱歉,我被家里的新生儿分心了!可能是一种方法,但我不认为它是最有效的方法,因为我没有花时间正确思考这个问题,但在最初评论之后,我确实想结束一个松散的结局。这不是一种完全的方法,但它与相等的OP检查匹配整个文件需要加载到内存中并在开始匹配之前进行解析。。。在AFAICS中,对于少量数据,速度优势可以忽略不计,对于大量数据,速度优势将无法放入内存中。我认为用熊猫来做这件事会有一个非常狭窄的甜蜜点。谢谢你表达了你的意思。是的,我们在记忆部分意见一致。“>100MB”是。。。摘要在它成为一个问题之前,这给了它很大的回旋余地,但它是开放的