В современной клининговой индустрии часто используют технологические карты (техкарты) – подробные схемы действий сотрудника на конкретном участке. При автоматизации планов уборки такие карты удобно хранить в виде двумерных массивов (матриц), где каждая строка – это объект, а каждый столбец – это операция. Часто возникает необходимость «убрать» (обнулить, заменить) элементы, расположенные по главной диагонали матрицы. В этой статье мы разберём:
- Что такое диагональ в контексте массивов и техкарт.
- Зачем может понадобиться удалять/заполнять её.
- Как правильно выполнять эту задачу в
Pythonс помощью библиотекиNumPy. - Практический пример: автоматическое формирование графика уборки.
Диагональ матрицы и её смысл в техкартах
Для любой квадратной матрицы A главная диагональ состоит из элементов A[i][i], где i меняется от 0 до n‑1. В контексте технологических карт:
- Строка – это конкретный объект (офис, склад, коридор).
- Столбец – это тип операции (пыль, пол, окна, дезинфекция).
- Элемент на диагонали
A[i][i]обычно обозначает само‑оценку – время, затраченное на объект, когда тип операции совпадает с названием объекта (например, «офис‑офис»).
В реальных планах такие «само‑операции» часто не нужны, их убирают, чтобы не учитывать их в расчётах времени и расходов.
Почему стоит «убирать» диагональ?
Существует несколько типовых сценариев:
- Исключение двойного учёта. Если в таблице указаны одинаковые операции для одного и того же помещения, они могут удваивать расчётные нормы.
- Подготовка к агрегированию. При суммировании по столбцам/строкам диагональные элементы могут вносить шум.
- Визуальная чистота отчётов. При выводе таблицы в Excel или в веб‑отчёте пустые клетки по диагонали делают её более читаемой.
Традиционные способы «убрать» диагональ в NumPy
Библиотека NumPy предлагает несколько методов. Рассмотрим их подробно.
Использование numpy.fill_diagonal
Самый простой и надёжный способ – вызвать функцию fill_diagonal и передать ей нужное значение (обычно 0 или np.nan).
import numpy as np
tech_map = np.array([
[10, 5, 3, 2, 1],
[ 4, 12, 6, 3, 2],
[ 2, 4, 15, 5, 3],
[ 1, 2, 4, 18, 4],
[ 0, 1, 2, 3, 20]])
np.fill_diagonal(tech_map, 0)
print(tech_map)
Результат:
[[ 0 5 3 2 1]
[ 4 0 6 3 2]
[ 2 4 0 5 3]
[ 1 2 4 0 4]
[ 0 1 2 3 0]]
Через индексы np.diag_indices
Если нужно выполнить более сложную операцию (например, заменить на np.nan), удобно получить индексы диагонали:
diag_idx = np.diag_indices(tech_map.shape[0])
tech_map[diag_idx] = np.nan # или любое другое значение
Срезы и маски
Для не квадратных массивов (например, 7 × 5) можно использовать маску:
rows, cols = np.minimum(tech_map.shape[:2], tech_map.shape[:2])
mask = np.arange(rows)
tech_map[mask, mask] = 0
Частые ошибки и как их избежать
- Неправильный тип массива. Функция
fill_diagonalработает только сndarray. Если у вас список списков – сначала преобразуйте:np.array(your_list). - Не квадратная матрица. По умолчанию
fill_diagonalзаполняет только те элементы, где индексы совпадают. В прямоугольных массивах она будет работать до минимального из размеров. - Изменение исходного массива. Функция изменяет массив «на месте». Если нужен оригинал – сделайте копию:
arr_copy = arr.copy. - Тип данных. При попытке записать
np.nanв массив целого типа получитеValueError. Преобразуйте тип:arr = arr.astype(float).
Практический пример: генерация графика уборки с «чистой» диагональю
Предположим, у вас есть 6 офисных помещений, каждое из которых требует пяти видов уборки. Вы хотите посчитать общее время, исключив «само‑уборку», то есть элементы по диагонали.
import numpy as np
time_matrix = np.random.randint(5, 20, size=(6, 5))
print("Исходная матрица времени:")
print(time_matrix)
np.fill_diagonal(time_matrix, 0)
total_per_room = time_matrix.sum(axis=1)
print("
Время на каждое помещение без диагонали:")
print(total_per_room)
total_all = time_matrix.sum
print("
Общее время уборки:", total_all, "минут")
Такой подход позволяет быстро сформировать отчёт о затратах и использовать его в технологических картах для планирования.
Как «убрать» не только главную, но и побочную диагональ
Если требуется очистить вторую диагональ (A[i][n‑i‑1]), используйте функцию np.fliplr (отражение слева‑направо) совместно с fill_diagonal:
n = tech_map.shape[0]
np.fill_diagonal(np.fliplr(tech_map), 0) # заполняем побочную диагональ нулями
Связь с реальными технологическими картами в клининге
В практике клининговых компаний (см. InfoClean) технологические карты часто хранятся в виде таблиц Excel. Автоматизация их обработки через Python/NumPy позволяет:
- Сократить время на подготовку ежедневных графиков.
- Устранить человеческие ошибки при копировании данных.
- Генерировать динамические отчёты (см. «живые» техкарты).
Например, если в таблице в колонке «Время (мин)» случайно попала дата (что часто происходит при импорте из CSV), её можно заменить на ноль, а потом «убрать» диагональ, чтобы исключить двойной учёт.
Убирать (обнулять, заменять) диагональ в массивах – простая, но важная операция при работе с технологическими картами клининговых компаний. Самый надёжный способ – воспользоваться numpy.fill_diagonal. Он быстро, читабельно и работает с массивами любой размерности.
Помните о типах данных, необходимости копировать массив при сохранении оригинала и о том, что в реальных проектах часто требуется обработать и побочную диагональ. С этими знаниями вы сможете автоматизировать большую часть рутинных расчётов, оставив больше времени для действительно важной работы – поддержания чистоты.
Дата актуализации: 10:51 UTC