Я думаю, что в том, чего вы пытаетесь достичь, многое происходит, но его можно разбить на два этапа.(и я не уверен, является ли какой-либо из них наиболее эффективным способом достижения цели)
- Найдите все пары людей, которые перекрываются друг с другом в течение минимального периода времени
- «Конденсировать» список пар в группы
Для первой задачи простой метод состоит в том, чтобы просто пройтись по каждому человеку и проверить, достаточно ли перекрывается любой другой человек.
Начиная с тестового фрейма данных (псевдослучайные времена и произвольные имена):
index person_name start_date end_date
0 Angelina 1510568169 1523357075
1 Na 1555533506 1568322412
2 Twyla 1558758901 1571547807
3 Wilfredo 1551369432 1564158338
4 Estefana 1515025466 1527814372
Мы можем найти пары с:
pairs = []
for i in range(len(test.index)):
for j in range(len(test.index)-i-1):
if (min(test.loc[i]['end_date'], test.loc[i+j+1]['end_date'])
- max(test.loc[i]['start_date'], test.loc[i+j+1]['start_date'])
>= (min_time_together)):
pairs.append([test.loc[i]['person_name'], test.loc[i+j+1]['person_name']])
Это сгенерирует вывод:
[['Angelina', 'Estefana'],
['Na', 'Twyla'],
['Na', 'Wilfredo'],
['Twyla', 'Wilfredo']]
Чтобы "сжать" этот список пар, нужно использовать теорию графов, которая, если честно, я не эксперт по НО, но вот удивительный ответ на связанный вопрос StackOverflow (Очень интересная тема и много хорошей информации на этой странице).Если мы используем функцию condenseBK
из этого ответа в нашем списке списков, мы получаем окончательный результат:
#condenseBK(*pairs)
[['Angelina', 'Estefana'], ['Na', 'Twyla', 'Wilfredo']]