Преобразование дат в хронологическом порядке с использованием pandas dataframe - PullRequest
0 голосов
/ 02 июня 2018

Мне нужна помощь в сравнении дат в разных строках и в разных столбцах и в том, что они следуют в хронологическом порядке.

Сначала я группирую данные на основе Id и группа столбцы.Далее, каждое значение даты должно происходить в будущем.

Первая группа [1111 + A] содержит ошибку, поскольку даты не следуют в хронологическом порядке:

1/1/2016  >  2/20/2016  > **2/19/2016** >  4/25/2016  >  **4/1/2016** >  5/1/2016

Текущий результат

      id       start         end group
0   1111  01/01/2016  02/20/2016     A
1   1111  02/19/2016  04/25/2016     A
2   1111  04/01/2016  05/01/2016     A
3   2345  05/01/2016  05/28/2016     B
4   2345  05/29/2016  06/28/2016     B
5   1234  08/01/2016  09/16/2016     F
6   9882  01/01/2016  08/29/2016     D
7   9992  03/01/2016  03/15/2016     C
8   9992  03/16/2016  08/03/2016     C
9   9992  05/16/2016  09/16/2016     C
10  9992  09/17/2016  10/16/2016     C
11  9992  10/17/2016  12/13/2016     C

Ответ должен быть следующим:

1/1/2016  >  2/20/2016  > **2/21/2016** >  4/25/2016  >  **4/26/2016** >     5/1/2016

Желаемый результат

      id       start         end group
0   1111  01/01/2016  02/20/2016     A
1   1111  02/21/2016  04/25/2016     A
2   1111  04/26/2018  05/01/2016     A
3   2345  05/01/2016  05/28/2016     B
4   2345  05/29/2016  06/28/2016     B
5   1234  08/01/2016  09/16/2016     F
6   9882  01/01/2016  08/29/2016     C
7   9992  03/01/2016  03/15/2016     C
8   9992  03/16/2016  08/03/2016     C
9   9992  08/04/2016  09/16/2016     C
10  9992  09/17/2016  10/16/2016     C
11  9992  10/17/2016  12/13/2016     C

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Я считаю, что это должно работать:

# First make sure your column are datetimes:
df['start'] = pd.to_datetime(df['start'])
df['end'] = pd.to_datetime(df['end'])

# Get your new start times:
new_times = (df.groupby(['id', 'group'])
               .apply(lambda x: (x.end + pd.Timedelta(days=1)).shift())
               .reset_index(['id', 'group'], drop=True))

# put back into original dataframe
df.loc[new_times.notnull(), 'start'] = new_times[new_times.notnull()]

>>> df
      id      start        end group
0   1111 2016-01-01 2016-02-20     A
1   1111 2016-02-21 2016-04-25     A
2   1111 2016-04-26 2016-05-01     A
3   2345 2016-05-01 2016-05-28     B
4   2345 2016-05-29 2016-06-28     B
5   1234 2016-08-01 2016-09-16     F
6   9882 2016-01-01 2016-08-29     D
7   9992 2016-03-01 2016-03-15     C
8   9992 2016-03-16 2016-08-03     C
9   9992 2016-08-04 2016-09-16     C
10  9992 2016-09-17 2016-10-16     C
11  9992 2016-10-17 2016-12-13     C

Пояснение :

new_times выглядит так:

>>> new_times
0           NaT
1    2016-02-21
2    2016-04-26
5           NaT
3           NaT
4    2016-05-29
6           NaT
7           NaT
8    2016-03-16
9    2016-08-04
10   2016-09-17
11   2016-10-17

Вы можетезатем используйте df.loc[new_times.notnull(), 'start'] = new_times[new_times.notnull()], чтобы найти, где new_times не является нулевым (т. е. где это не первая строка в данной группе), и вставьте эти new_times в исходный столбец start.

0 голосов
/ 02 июня 2018

Один из способов - применить вашу логику к каждой группе, а затем объединить ваши группы.

# convert series to datetime
df['start'] = pd.to_datetime(df['start'])
df['end'] = pd.to_datetime(df['end'])

# iterate groups and add results to grps list
grps = []
for _, group in df.groupby(['id', 'group'], sort=False):
    end_shift = group['end'].shift()
    group.loc[group['start'] <= end_shift, 'start'] = end_shift + pd.DateOffset(1)
    grps.append(group)

# concatenate dataframes in grps to build a single dataframe
res = pd.concat(grps, ignore_index=True)

print(res)

      id      start        end group
0   1111 2016-01-01 2016-02-20     A
1   1111 2016-02-21 2016-04-25     A
2   1111 2016-04-26 2016-05-01     A
3   2345 2016-05-01 2016-05-28     B
4   2345 2016-05-29 2016-06-28     B
5   1234 2016-08-01 2016-09-16     F
6   9882 2016-01-01 2016-08-29     D
7   9992 2016-03-01 2016-03-15     C
8   9992 2016-03-16 2016-08-03     C
9   9992 2016-08-04 2016-09-16     C
10  9992 2016-09-17 2016-10-16     C
11  9992 2016-10-17 2016-12-13     C
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...