Кажется, что вы хорошо знакомы с Python, но я все равно попытаюсь объяснить некоторые из этих шагов. Начнем с первого вопроса о деплюралировании слов. Когда вы читаете в многострочном файле (слово, csv в вашем случае) с помощью a.read(), вы будете читать весь массив файла в одну большую строку.
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
Это хорошо и все, но если вы хотите, чтобы передать результат в стебле(), то это будет как одна большая строка, а не как список слов. Это означает, что когда вы перебираете вход с помощью 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 (е) следующим образом:
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
Это должно дать нам б как список строк, то есть [ 'Soc, 32', 'Soc, 1', ...]. Таким образом, следующая проблема становится тем, что мы делаем со списком строк, когда мы передаем ее стеку(). Один из способов заключается в следующем:
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
Это, безусловно, довольно грубое решение, но должны адекватно перебрать все строки в вашем входе и depluralize их. Это грубо, потому что разделение строк и их повторная сборка не особенно быстро, когда вы масштабируете его. Однако, если вас это устраивает, все, что осталось, это перебрать список новых строк и записать их в ваш файл. По моему опыту, обычно безопаснее писать в новый файл, но это должно работать нормально.
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
Второй вопрос, связанный с объединением чисел с теми же словами, изменяет наше решение сверху. Согласно предложению в комментариях, вы должны взглянуть на использование словарей, чтобы решить эту проблему. Вместо того, чтобы делать все это как один большой список, лучший (и, вероятно, более пуфонический) способ сделать это состоит в том, чтобы перебирать каждую строку вашего ввода и прерывать их при их обработке. Я напишу код об этом немного, если вы все еще работаете, чтобы понять это.
Чтобы попытаться свернуть все значения в одну строку за слово, я рекомендую смотреть вверх [словари в документации] (https: // документы .python.org/2/учебник/datastructures.html # словари). – SuperBiasedMan
Вы хотите сделать что-нибудь с множественными числами, которые не заканчиваются на 's'? то есть. Гуси? Потому что это становится намного сложнее, чем удаление конечных s. Кроме того, как насчет того, когда слово заканчивается на 's', например. 'Класс'. Должен ли ваш скрипт обрабатывать любое слово или есть меньший, более конкретный пул, на который он может нарисовать? – SuperBiasedMan
Нет, я просто хочу удалить s, по крайней мере на данный момент – theintern