Как вы говорили, метод groupby
объекта pd.DataFrame
может выполнять задание.
Пример
L = ['A','A','B','B','B','C']
N = [1,2,5,5,4,6]
import pandas as pd
df = pd.DataFrame(zip(L,N),columns = list('LN'))
groups = df.groupby(df.L)
groups.groups
{'A': [0, 1], 'B': [2, 3, 4], 'C': [5]}
, который дает и индексное описание групп.
Чтобы получить элементы отдельных групп, вы можете сделать, например
groups.get_group('A')
L N
0 A 1
1 A 2
groups.get_group('B')
L N
2 B 5
3 B 5
4 B 4
В дополнение к инициализации значения каждого «new_thing» до 0 (cloud[new_thing] = 0
), как отмечали другие, существует еще одна серьезная проблема: вы пытаетесь выполнить итерацию по cloud
перед добавлением к ней какого-либо элемента (таким образом, for new_thing in cloud:
и его блок эффективно ничего не делают, потому что cloud
пуст). Это необязательно, поскольку словари доступны не последовательно.
Вы можете либо заменить
new_thing = thing.strip(string.punctuation)
cloud[new_thing] = 0
for new_thing in cloud:
cloud[new_thing] = cloud.get(new_thing, 0) + 1
просто:
new_thing = thing.strip(string.punctuation)
cloud[new_thing] = cloud.get(new_thing, 0) + 1
, либо использовать кнопку collections.Counter
, который, как утверждают другие, уже делает то, что вы пытаетесь выполнить, и, вероятно, облегчит задачу.
В вашем коде для каждой новой строки вы устанавливаете
cloud[new_thing] = 0
, который сбрасывает счетчик для слова new_thing
.
Поскольку вы уже используете cloud.get(new_thing, 0)
, который вернет 0
, если ключ new_thing
не найден, вы можете просто удалить эту строку.
Я бы извлек часть, которая разбивает файл в строках и словах, и линяет пунктуацию:
def strip_punctuation(lines):
for line in lines:
for word in line:
yield word.strip(string.punctuation)
with open('objects.txt', 'r') as file:
cloud = collections.Counter(strip_punctuation(file))
или, еще более кратким, используя itertools.chain
и map
:
with open('objects.txt', 'r') as file:
words = itertools.chain.from_iterable(file)
words_no_punctuation = map(lambda x: x.strip(string.punctuation))
cloud = collections.Counter(words_no_punctuation)
PS: for thing in line:
не разбивает строку словами, а символами. Я думаю, вы имеете в виду for thing in line.split():
, тогда последний вариант будет:
with open('objects.txt', 'r') as file:
words_per_line = map(lambda line: line.split(), file)
words = itertools.chain.from_iterable(words_per_line)
words_no_punctuation = map(lambda x: x.strip(string.punctuation))
cloud = collections.Counter(words_no_punctuation)
вы можете использовать функцию setdefault
словаря python
for new_thing in cloud:
count = cloud.setdefault(new_thing, 0)
cloud[new_thing] = count + 1