Pandas Python — сравнение разных диапазонов дат и проверка того, находятся ли они в одном и том же периоде времени

В настоящее время я решаю проблему, и мне порекомендовали использовать «Pandas», так как это подходит для моего решения, поэтому приношу свои извинения, так как я новичок в пакете «Pandas».

Проблема, которую я пытаюсь решить, состоит в том, чтобы прочитать текстовый файл с такими данными:

EmpID,ProjectID,DateFrom,DateTo
1,100,2014-11-01,2015-05-01
2,101,2013-12-06,2014-10-06
3,102,2015-06-04,2017-09-04
5,103,2014-10-01,2015-12-01
2,100,2013-03-07,2015-11-07
2,103,2015-07-09,2019-01-19
4,102,2013-11-13,2014-03-13
4,103,2016-02-14,2017-03-15
5,104,2014-03-15,2015-11-09

Теперь моей задачей было сказать, какие сотрудники дольше всех работали вместе над общим проектом.

Это мой прогресс до сих пор:

import pandas as pd
import datetime as dt
import numpy as np

date_parser = lambda c: pd.to_datetime(c, format='%Y/%m/%d', errors='coerce')
df = pd.read_csv('data.csv', delimiter = ',', parse_dates=[2,3], date_parser=date_parser)
#df.set_index("EmpID", inplace = True)
df.sort_values(['ProjectID'], inplace=True)
df['Days Worked'] = (df['DateTo'] - df['DateFrom']).dt.days
cutdown_projecs = df.groupby('ProjectID').filter(lambda x: len(x) >= 2)

print(cutdown_projecs)

Что я делаю, так это упорядочиваю таблицу, придаю значениям даты правильный формат, сортирую по ProjectID, а затем сокращаю до проектов, которые повторяются два или более раз (так как это означало бы, что сотрудники работали над ними вместе). Я также добавил новый столбец, который добавляет «Отработанные дни». Что приводит меня к следующему результату:

     EmpID  ProjectID   DateFrom     DateTo      Days Worked
0      1        100    2014-11-01 2015-05-01          181
4      2        100    2013-03-07 2015-11-07          975
2      3        102    2015-06-04 2017-09-04          823
6      4        102    2013-11-13 2014-03-13          120
3      5        103    2014-10-01 2015-12-01          426
5      2        103    2015-07-09 2019-01-19         1290
7      4        103    2016-02-14 2017-03-15          395

Теперь мне нужен совет, как правильно подойти к проблеме. Мне как-то нужно проверить, какие диапазоны данных «сталкиваются» в одном проекте, а затем вместе посчитать рабочие дни сотрудников. Я был бы очень признателен, если бы вы могли дать мне чаевые. Спасибо.

Обновлено: Исправлена ​​​​таблица.

Вы хотите знать это для каждой пары EmpID или для всех EmpID в проекте? Каков ваш ожидаемый результат для игрушечного набора данных выше?

Quang Hoang 29.05.2019 21:38

@QuangHoang Я просто хочу узнать о паре EmpID, у которой самое продолжительное время совместной работы над проектом. Я только что заметил, что таблица испортилась из-за форматирования, и я это исправлю.

Gergan Zhekov 29.05.2019 21:40
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
2
364
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я придумал решение, но не знаю, соответствует ли оно вашим потребностям. Это максимальное время совместной работы двух сотрудников.

from collections import defaultdict
from itertools import combinations
from datetime import datetime

data ='''\
1,100,2014-11-01,2015-05-01
2,101,2013-12-06,2014-10-06
3,102,2015-06-04,2017-09-04
5,103,2014-10-01,2015-12-01
2,100,2013-03-07,2015-11-07
2,103,2015-07-09,2019-01-19
4,102,2013-11-13,2014-03-13
4,103,2016-02-14,2017-03-15
5,104,2014-03-15,2015-11-09'''.splitlines()

d = defaultdict(list)
for line in data:
    empID, job, start, finish = line.split(',')
    d[job].append([empID,start,finish])

for job, aref in d.items():
    if len(aref) >= 2:
        for ref in combinations(aref, 2):
            begin = max(map(lambda x: x[1], ref))
            end = min(map(lambda x: x[2], ref))
            delta = datetime.strptime(end, '%Y-%m-%d') \
                    - datetime.strptime(begin, '%Y-%m-%d')
            dd = delta.days
            if dd > 0:
                print('employees', ref[0][0], 'and', ref[1][0],
                      'worked together', dd, 'days on job', job)

Выход был:

employees 1 and 2 worked together 181 days on job 100
employees 5 and 2 worked together 145 days on job 103
employees 2 and 4 worked together 395 days on job 103
>>> 

Большое спасибо! Это отличное решение, и я думаю, что потратил пару часов на панд (но это еще не время впустую!). Я просто попытаюсь адаптировать ваш код, заставить его читать данные из .csv/.txt (вместо имеющейся у вас переменной данных), что, я надеюсь, будет достаточно легко сделать. Мне также интересно, есть ли способ для кода принять «NULL» в качестве сегодняшней даты. Еще раз спасибо!!!

Gergan Zhekov 29.05.2019 22:53

@Gergan Zhekov Рад, что был вам полезен! Я отредактировал код для одного случая if len(aref) >= 2: и получил те же результаты, что и исходная попытка. Я не знаю, как справиться NULL. Я не работал с pandas, но это похоже на более короткое решение (из вашего кода).

Chris Charley 29.05.2019 23:01

Другие вопросы по теме