Это таблица , над которой я работаю.Как видите, электронная таблица находится в очень грязном состоянии.Я провел некоторую очистку данных в соответствии с описанием ниже:
- Каждый заголовок столбца обозначает Период / урок дня
- Каждый день имеет 7 периодов / уроков, поэтому понедельникпо пятницам = 35 столбцов
- каждая ячейка содержит дескриптор класса (первые 3 символа), интелитуры учителя (3 символа после знака «$») и название комнаты (3 символа после"(").
Я хочу объединить учителей в группы по 3 (триады), где выполняются следующие критерии:
- В любой данный период / урок2 недели учителя «свободны», не преподают, а 1 учитель преподает.
- В той же самой триаде в другой период есть другой учитель, который «несвободен» и обучает, где два других учителяпреподают
- , кроме того, в любой другой период другая комбинация из двух учителей, являющихся «бесплатными» неучащими, и неиспользованный учитель учат.
См. нижеa для дальнейшего разъяснения:
Инициалы A и B находятся в наборе, но отсутствуют в C, присутствуют в наборе, а также C и A в наборе, но не присутствуют в наборе, а также B и C в наборе, но не присутствуют в Aнабор Все 3 критерия должны быть верны, чтобы найти окончательную триаду
, поэтому из тысяч перестановок должно быть не так много комбинаций, которые соответствуют этим критериям
Проще говоря, что яПопытка найти - это поместить учителей в группы по 3 человека. Где 2 учителя могут пойти и понаблюдать за уроком другого учителя, то есть в любой период 2 учителя свободны, а один преподает.В каждой колонке вы увидите всех учителей, которые преподают в любой конкретный период и день.Поэтому тот, кто не находится в этой колонке, которую мы можем вывести, не учит.Мы хотим, чтобы группа из трех учителей оставалась триадой, чтобы каждого из нас можно было наблюдать.Таким образом, в любой другой период недели другой учитель преподает из той же триады, а два других НЕ преподают.
Это код, который я написал до сих пор для очистки данных и создания возможных триад.Я не знаю, является ли это лучшим подходом к вышеупомянутой проблеме, но в любом случае это то, что я сделал до сих пор.В настоящее время я застрял в том, как я могу найти пересечения между всеми этими триадами, чтобы правильно определить учителей, которые удовлетворяют вышеуказанным критериям.
import pandas as pd
import numpy as np
import itertools
class unique_element:
def __init__(self,value,occurrences):
self.value = value
self.occurrences = occurrences
def perm_unique(elements):
eset=set(elements)
listunique = [unique_element(i,elements.count(i)) for i in eset]
u=len(elements)
return perm_unique_helper(listunique,[0]*u,u-1)
def perm_unique_helper(listunique,result_list,d):
if d < 0:
yield tuple(result_list)
else:
for i in listunique:
if i.occurrences > 0:
result_list[d]=i.value
i.occurrences-=1
for g in perm_unique_helper(listunique,result_list,d-1):
yield g
i.occurrences+=1
def findsubsets(S, m):
return set(itertools.combinations(S, m))
csv_file = pd.read_csv('Whole_School_TT.csv')
df = csv_file.dropna(how='all')
df = csv_file.fillna(0)
cols = df.columns
df_class_name = df.copy()
df_names = df.copy()
df_room_number = df.copy()
for col in range(0, len(df.columns)):
for row in range(0, len(df)):
if df[cols[col]].iloc[row] is not 0:
text = df[cols[col]].iloc[row]
index_dollar = df[cols[col]].iloc[row].find('$')
r_index_dollar = df[cols[col]].iloc[row].rfind('$')
if index_dollar is not -1:
if index_dollar == r_index_dollar:
df_names[cols[col]].iloc[row] = df[cols[col]].iloc[row][index_dollar+1:index_dollar+4]
else:
name1 = df[cols[col]].iloc[row][index_dollar + 1:index_dollar + 4]
name2 = df[cols[col]].iloc[row][r_index_dollar + 1:r_index_dollar + 4]
df_names[cols[col]].iloc[row] = name1 + ' ' + name2
index_hash = df[cols[col]].iloc[row].find('#')
df_class_name[cols[col]].iloc[row] = df[cols[col]].iloc[row][:(index_dollar - 1)]
df_room_number[cols[col]].iloc[row] = df[cols[col]].iloc[row][index_hash + 1:-1]
else:
df_names[cols[col]].iloc[row] = 0
index_hash = df[cols[col]].iloc[row].find('#')
if index_hash is -1:
df_class_name[cols[col]].iloc[row] = df[cols[col]].iloc[row][:3]
df_room_number[cols[col]].iloc[row] = 0
else:
df_class_name[cols[col]].iloc[row] = df[cols[col]].iloc[row][:(index_hash - 2 )]
df_room_number[cols[col]].iloc[row] = df[cols[col]].iloc[row][index_hash + 1:-1]
teacher_names = []
for col in range(0, len(cols)):
period_names = (df_names[cols[col]].unique())
teacher_names.extend(period_names)
df_all_names = pd.DataFrame(teacher_names, columns=['Names'])
df_all_names = pd.DataFrame(df_all_names['Names'].unique())
df_all_names = df_all_names[(df_all_names.T != 0).any()]
mask = (df_all_names[0].str.len() == 3)
df_single_names = df_all_names.loc[mask] # so now here we have all the teacher names in general who teach
# we will find the teacher who teach per period and teachers who do not teach
set_of_names = set(np.array(df_single_names[0])) # here i have all the unique teacher names
period_set_names = [0]*len(cols)
period_set_names_NO_teach = [0]*len(cols)
# here i get the names for each one of the periods
# and find the intersection with the unique teacher names in order to figure out who teaches per period
for col in range(0, len(cols)):
period_set_names[col] = set(np.array(df_names[cols[col]])) # get teacher names for current period
period_set_names_NO_teach[col] = set_of_names.difference(period_set_names[col])
period_set_names[col] = set_of_names.intersection(period_set_names[col])
# sanity check
print('Teachers who teach and teacher who dont teach should be equivalent to the full list of names: ', end='')
print(period_set_names_NO_teach[col].union(period_set_names[col]) == set_of_names)
def get_current_period_triplets(col):
free_period_pairs = findsubsets(period_set_names_NO_teach[col], 2) # I got all the period Free teacher pairs
# teaching_period_pairs = findsubsets(period_set_names[col], 2)
free_period_pairs_list = list(free_period_pairs)
period_triplets = []
for i in range(0, len(free_period_pairs_list)):
listof = list(free_period_pairs_list)
current_free_pair = list(listof[i])
# print(current_free_pair)
for j in (period_set_names[col]):
temp = current_free_pair.copy()
current_triplet = temp.append(j)
period_triplets.append(tuple(temp))
period_triplets = set(period_triplets)
return period_triplets
for col in range(0, len(cols)):
current_triplets = get_current_period_triplets(col)
print(current_triplets)