您似乎对Python相当熟悉,但我仍将尝试解释其中的一些步骤。让我们从第一个使单词复数的问题开始。当您使用a.read()读取多行文件(在本例中为单词,数字csv)时,您将需要将文件的整个主体读取为一个大字符串。
def openfile(f):
with open(f,'r') as a:
a = a.read() # a will equal 'soc, 32\nsoc, 1\n...' in your example
a = a.lower()
return a
一切都很好,但是当您要将结果传递给stem()时,它将是一个大字符串,而不是单词列表。这意味着,当您使用遍历输入时for word in a
,将遍历输入字符串的每个单个字符,并将词干应用于这些单个字符。
def stem(a):
p = nltk.Porterstemmer()
a = [p.stem(word) for word in a] # ['s', 'o', 'c', ',', ' ', '3', '2', '\n', ...]
return a
这绝对不能满足您的目的,我们可以做一些不同的事情。
只是为了方便起见,让我们一起尝试#1。这将需要将openfile(f)更改为以下内容:
def openfile(f):
with open(f,'r') as a:
a = a.readlines() # a will equal 'soc, 32\nsoc, 1\n...' in your example
b = [x.lower() for x in a]
return b
这应该给我们b作为行的列表,即[‘soc,32’,’soc,1’,…]。因此,下一个问题变成当将字符串列表传递给stem()时,我们该如何处理它。一种方法如下:
def stem(a):
p = nltk.Porterstemmer()
b = []
for line in a:
split_line = line.split(',') #break it up so we can get access to the word
new_line = str(p.stem(split_line[0])) + ',' + split_line[1] #put it back together
b.append(new_line) #add it to the new list of lines
return b
这绝对是一个很粗糙的解决方案,但是应该对输入中的所有行进行足够的迭代,并使它们复数。这很粗糙,因为在放大时,分割字符串和重新组装它们并不是特别快。但是,如果对此感到满意,那么剩下的就是遍历新行列表,并将它们写入文件。以我的经验,写入新文件通常更安全,但这应该可以正常工作。
def returnfile(f, a):
with open(f,'w') as d:
for line in a:
d.write(line)
print openfile(f)
print stem(openfile(f))
print returnfile(f, stem(openfile(f)))
当我有以下 input.txt时
soc, 32
socs, 1
dogs, 8
我得到以下标准输出:
Please enter a filename: input.txt
['soc, 32\n', 'socs, 1\n', 'dogs, 8\n']
['soc, 32\n', 'soc, 1\n', 'dog, 8\n']
None
而 input.txt 看起来像这样:
soc, 32
soc, 1
dog, 8
关于将数字与相同词合并的第二个问题从上面改变了我们的解决方案。根据评论中的建议,您应该看看使用字典来解决此问题。与其将所有内容作为一个大列表而不是一味列出来,更好的方法(可能是更多的pythonic方法)是遍历输入的每一行,并在处理它们时阻止它们。如果您仍在努力找出答案,我会写一些有关此的代码。