Панды: создать столбец, где строка равна строке ниже в другом столбце - PullRequest
0 голосов
/ 20 февраля 2019
df1 = pd.DataFrame({'id':[44,44,44,88,88,90,95],
               'Old Status': ['Draft','Submit','Return','Submit','Accept',
               'Draft','Draft'],
               'New Status' : ['Submit','Return','Reject','Accept','Develop',
                              'Submit','Reject'],
                              'Datetime': ['2018-10-24 08:12:02',
                              '2018-10-24 18:12:02', '2018-11-24 08:56:02',
                              '2018-10-24 10:12:02','2018-10-29 13:17:02',
                              '2018-12-30 08:43:12', '2019-01-24 06:12:02']
                              }, columns = ['id','Old Status', 'New Status', 'Datetime'])
df1['Datetime'] = pd.to_datetime(df1['Datetime'])                              
df1
   id Old Status New Status            Datetime
0  44      Draft     Submit 2018-10-24 08:12:02
1  44     Sumbit     Return 2018-10-24 18:12:02
2  44     Return     Reject 2018-11-24 08:56:02
3  88     Submit     Accept 2018-10-24 10:12:02
4  88     Accept    Develop 2018-10-29 13:17:02
5  90      Draft     Submit 2018-12-30 08:43:12
6  95      Draft     Reject 2019-01-24 06:12:02

У меня есть фрейм данных в указанном выше формате, но мне нужно упростить процесс визуализации данных, поэтому мне нужны два столбца: «Статус входа» и «Дата выхода статуса».«Status In» будет равно столбцу Datetime.loc[n], Status Out будет равно Datetime.loc[n+1] для любого id.

Когда в следующей строке есть новый id, это можно предположить какNew Status - это текущий статус, поэтому Status Out будет null.

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

Пока у меня есть следующее.Затем я планирую добавить условные выражения для обработки id изменений и затем преобразовать их в кадр данных, но это выглядит так неправильно:

df['Status In'] = df['Datetime']
s_out = [0]*(df['Status In'].count()-1)
for el in range(0,df['Status In'].count()-1):
    s_out[el] = df['Status In'].iloc[el+1]

Конечный результат будет выглядеть примерно так:

   id Old Status New Status           Status In           Status Out
0  44      Draft     Submit 2018-10-24 08:12:02  2018-10-24 18:12:02
1  44     Sumbit     Return 2018-10-24 18:12:02  2018-11-24 08:56:02
2  44     Return     Reject 2018-11-24 08:56:02                  NaN
3  88     Submit     Accept 2018-10-24 10:12:02  2018-10-29 13:17:02
4  88     Accept    Develop 2018-10-29 13:17:02                  NaN
5  90      Draft     Submit 2018-12-30 08:43:12                  NaN
6  95      Draft     Reject 2019-01-24 06:12:02                  NaN

Есть ли лучший, более чистый способ сделать это в Python / Pandas без использования циклов for и операторов if?

1 Ответ

0 голосов
/ 20 февраля 2019

Сначала используйте shift, а затем Series.where по маске eq:

shifted = df1.groupby('id')['Datetime','Old Status'].shift(-1)
print (shifted)
             Datetime Old Status
0 2018-10-24 18:12:02     Submit
1 2018-11-24 08:56:02     Return
2                 NaT        NaN
3 2018-10-29 13:17:02     Accept
4                 NaT        NaN
5                 NaT        NaN
6                 NaT        NaN

df1['Status Out'] = shifted['Datetime'].where(df1['New Status'].eq(shifted['Old Status']))
print (df1)
   id Old Status New Status            Datetime          Status Out
0  44      Draft     Submit 2018-10-24 08:12:02 2018-10-24 18:12:02
1  44     Submit     Return 2018-10-24 18:12:02 2018-11-24 08:56:02
2  44     Return     Reject 2018-11-24 08:56:02                 NaT
3  88     Submit     Accept 2018-10-24 10:12:02 2018-10-29 13:17:02
4  88     Accept    Develop 2018-10-29 13:17:02                 NaT
5  90      Draft     Submit 2018-12-30 08:43:12                 NaT
6  95      Draft     Reject 2019-01-24 06:12:02                 NaT
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...