Пролог
Я очень рекомендую вам прочитать ЛЮБУЮ хорошую книгу по программированию, которая объясняет алгоритмы. Ваша проблема может быть решена буквально несколькими строками кода.
Акт 1
Посмотри на свою проблему. У вас есть несколько профессий, несколько возрастных групп и имена в качестве уникальных идентификаторов. И вы хотите отличать их друг от друга. Теперь посмотрите на ваш код. Для решения вашей проблемы вы создаете уникальный список для каждой комбинации возраста и профессии. Это наименее модифицируемая структура, которую можно создать. Если вам придется добавить еще пять профессий (есть тысячи различных профессий), вам придется буквально удвоить свой код. Более того, вы можете легко сделать ошибку при копировании. Обычный merchandiser3
вместо merchandiser4
может превратить ваши следующие два часа в ад от красных глаз. Смотри, у тебя уже есть ошибка внутри твоего кода!
if (line['profession'] == 'doctor' and line['age'] >= '13' and line['age'] <= '17'):
doctors1.append(line['name'])
if (line['profession'] == 'doctor' and line['age'] >= '18' and line['age'] <= '29'):
doctors2.append(line['name'])
if (line['profession'] == 'doctor' and line['age'] >= '30' and line['age'] <= '49'):
doctors3.append(line['name'])
if (line['profession'] == 'doctor' and line['age'] >= '50' and line['age'] <= '64'):
# Hello, guys! I am ready to torture his brain and eyes for hours!!
drivers4.append(line['name'])
if (line['profession'] == 'doctor' and line['age'] >= '65'):
doctors5.append(line['name'])
И, как последний выстрел в голову, вам не нужны все эти списки. Вы можете создать, например, дикт для каждой профессии. Или что-то другое. Но вы можете заметить, что ваши данные имеют очень-очень повторяющуюся структуру для каждого человека. Имя, возраст, профессия ... Подождите, где мы взяли данные? CSV файл? И что такое файл CSV?
Да.
Таблица.
Акт 2
Если вы читаете данные из таблицы, рекомендуется сохранить эти данные в таблице! (Ну, большую часть времени ...) В Python есть замечательная библиотека для таблиц - Pandas. Все ваши сотни строк могут быть сокращены до одной-двух десятков! Теперь внимательно посмотри на мои руки, магия начинается ...
Ноль. Мы импортируем панд:
import pandas as pd
Во-первых. Мы создаем отдельную функцию для возрастной кластеризации. Если наш Большой Босс скажет нам, чтобы мы справились с 11-летними нейробиологами, мы будем в полной готовности:
def get_age_cluster(age):
a = int(age)
if a >= 0 and a <= 12:
return '<13'
if a >= 13 and a <= 17:
return '13-17'
if a >= 18 and a <= 29:
return '18-29'
if a >= 30 and a <= 49:
return '30-49'
if a >= 50 and a <= 64:
return '50-64'
elif a >= 65:
return '>64'
Во-вторых. Мы читаем CSV. Вы делаете это вручную, строка за строкой, обрабатывая каждую возможную комбинацию ... Почему ?! Это обычная операция! Люди уже написали это давным-давно! Будьте ленивы!
(Это совет моего старого сенсея, который я храню в своем сердце годами! Шутка. У меня нет сердца.)
df=pd.read_csv('TF.csv')
Да, это все. Да. В самом деле. Одна линия. Двадцать четыре символа (запомните это число !!). Теперь давайте подружимся с нашими десятью маленькими милашками:
Мы только что загрузили CSV, но не преобразовали столбец age
. Он содержит возрасты, но должен содержать кластеры. Не проблема!
df['age'] = df['age'].apply(get_age_cluster)
Готово! Вы можете применять любые функции преобразования к строкам или столбцам таблицы. Таким образом, нам не нужно сортировать возрасты, сортировать возрасты и возрасты, сортировать возрасты и ... Мы можем просто написать красивую строчку. Вот результат:
Вы можете заметить, что у нас есть несколько столбцов мусора. Не проблема!
df = df.drop('waka', axis=1)
df = df.drop('we_dont_need_this_column', axis=1)
И у нас есть маленький красивый столик:
Теперь к основному заданию. Получить все имена в соответствии с каждой профессией и возрастом. Панды имеют много-много функций с группировкой. Давайте использовать самое простое:
grouped = df.groupby(['profession', 'age'])
for group in grouped.groups:
print(group, list(grouped.get_group(group)['name']))
Мы получаем сгруппированную структуру с возрастными группами профессий: grouped = df.groupby(['profession', 'age'])
, и для каждой группы в этой структуре: for group in grouped.groups:
мы печатаем: print()
список столбцов 'name' в каждой группе: grouped.get_group(group)['name'])
, И вот результат:
('eng', '30-49') ['Cthulhu']
('driver', '18-29') ['John Doe 3']
('actor', '13-17') ['John Doe 4']
('actor', '18-29') ['Yog-Sothoth']
('teacher', '18-29') ['John Doe 2', 'Shub-Niggurath']
('eng', '>64') ['Fblthp the Lost']
('driver', '<13') ['Azathoth']
('doctor', '18-29') ['Nyarlathotep']
('doctor', '30-49') ['John Doe 1']
А вот и весь код:
import pandas as pd
def get_age_cluster(age):
a = int(age)
if a >= 0 and a <= 12:
return '<13'
if a >= 13 and a <= 17:
return '13-17'
if a >= 18 and a <= 29:
return '18-29'
if a >= 30 and a <= 49:
return '30-49'
if a >= 50 and a <= 64:
return '50-64'
elif a >= 65:
return '>64'
df=pd.read_csv('TF.csv')
df['age'] = df['age'].apply(get_age_cluster)
df = df.drop('waka', axis=1)
df = df.drop('we_dont_need_this_column', axis=1)
grouped = df.groupby(['profession', 'age'])
for group in grouped.groups:
print(group, list(grouped.get_group(group)['name']))
Двадцать четыре строки. Я думаю, что теперь мы можем называть себя Фантастической Двадцатью Четверкой. Это как Фантастическая четверка, но Фантастическая двадцать четвертая. Но у нас все еще есть наш Graph Doom ...
Акт 3
Мы создали таблицу, сделали некоторые преобразования, отсортировали и отфильтровали ее. Но у вас есть другая проблема - График. И эта проблема сложнее, чем первая.
Вы читаете узлы (люди) и ребра (я не знаю, что именно. Отношения?) Из одного файла.Это заставляет ваш граф иметь сильное ограничение - количество узлов равно количеству ребер.Это очень редкий случай.Я думаю, что вы сделали что-то не так прямо перед тем, как начали писать этот сценарий.Я рекомендую вам иметь разные файлы (или, по крайней мере, разные секции в одном файле) для узлов и ребер.Но!Давайте предположим, что вы делаете именно то, что хотите, и у каждого человека (и, конечно, Ктулху!) Есть только одно преимущество.В этом случае мы можем построить наш граф только с двумя строками кода:
G = nx.Graph()
G.add_edges_from(df[['first', 'second']].values)
Бинго!Мы сделали.Теперь давайте возьмем эту странную сложную вещь:
Установите сообщество каждого узла (ЗАМЕЧАНИЕ, ЧТО ВАМ НУЖНО ДЛЯ АЛГОРИТМА):
for n in G.nodes:
G.nodes[n]['community'] = 0
И вычислите ЭТО:
csh = nx.cn_soundarajan_hopcroft(G)
И мы получаем итератор.Преобразуйте его в список и получите результат:
[(1, 8, 2),
(1, 9, 0),
(1, 2, 4),
(1, 4, 0),
(1, 6, 2),
(2, 8, 2),
(2, 9, 2),
(2, 5, 0),
(2, 6, 2),
(3, 9, 0),
(3, 4, 2),
(3, 5, 2),
(3, 6, 0),
(3, 7, 4),
(4, 8, 0),
(4, 5, 2),
(4, 7, 2),
(5, 8, 0),
(5, 9, 0),
(5, 7, 2),
(6, 8, 0),
(6, 9, 2),
(6, 7, 0),
(7, 8, 0),
(7, 9, 0),
(8, 9, 0)]
Grand Finale
Надеюсь, вам понравилась моя маленькая музыкальная пьеса, которую я для вас написал :) I рекомендую написать хорошую книгу по программированию на Python и книгу по алгоритмам.Удачи!