Создать новую переменную на основе сравнения групп и значений - PullRequest
0 голосов
/ 20 декабря 2018

Прошу прощения за не совсем правильное название этого поста.Задание состоит из нескольких частей, я не знаю, как именно сформулировать.У меня есть такой фрейм данных

df = pd.DataFrame({'id': (1,1,1,2,2), 'begin': ('01.01.2018','01.02.2018', '01.03.2018', '01.01.2018', '01.02.2018'),
    'end': ('01.02.2018','01.03.2018', '01.04.2018', '01.02.2018', '01.03.2018')})
df['begin']= pd.to_datetime(df['begin'])
df['end']= pd.to_datetime(df['end'])
df
      begin        end     id
0   2018-01-01  2018-01-02  1
1   2018-01-02  2018-01-03  1
2   2018-01-03  2018-01-04  1
3   2018-01-01  2018-01-02  2
4   2018-01-02  2018-01-03  2

, где begin - время начала проекта, end - время окончания проекта, а id - сотрудник.Я хочу создать новую переменную

      begin       end      id  new
0   2018-01-01  2018-01-02  1   3
1   2018-01-02  2018-01-03  1   2
2   2018-01-03  2018-01-04  1   1
3   2018-01-01  2018-01-02  2   2
4   2018-01-02  2018-01-03  2   1

. new указывает число незакрытых проектов на дату для конкретного сотрудника.В строке 0 значение равно 3, поскольку время начала проекта 2018-01-01, и у этого сотрудника есть три текущих проекта на эту дату.

Как я решил эту проблему Сначала мне нужно получить списокДаты окончания / начала проекта для каждого сотрудника

gr_end = df.groupby(['id'])['end'].apply(list)
gr_begin = df.groupby(['id'])['begin'].apply(list)

А сейчас самое сложное.Я должен сравнить дату начала проекта для каждого сотрудника с датой окончания каждого проекта.Я должен рассчитать все случаи, когда дата начала меньше, чем дата окончания

l = []
for i in gr_begin.index:
    for x in gr_begin[i]:
        cv = [j == 1 for j in gr_end[i] if j > x].count(False)
        l.append(cv)
df['new'] = l

Прежде всего, я прошу вас проверить, правильно ли я написал цикл.И самое главное, я считаю, что это можно сделать, но гораздо короче и удобнее.Буду благодарен за любую идею.

1 Ответ

0 голосов
/ 20 декабря 2018

Вы также можете сделать это с merge

merged = df.merge(df.drop(columns='end'), on='id', suffixes=('', '_y'))
live_projects = merged[merged.begin<=merged.begin_y]
result = live_projects.groupby(['id','begin','end']).count().reset_index()
result.rename(columns={'begin_y':'new'}, inplace=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...