Попытка смешать / объединить значения столбцов в нескольких строках в одну строку - PullRequest
2 голосов
/ 31 января 2020

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

Например

d = pd.DataFrame([['0001', None, 'backlog', '2020-01-15', '2020-01-31'], 
                  ['0001', 'backlog', 'complete', '2020-01-31', '9999-12-31'],
                  ['0001', 'backlog', 'complete', '2020-01-31', '9999-12-31'],
                  ['0002', None, 'backlog', '2019-02-15', '2019-02-25'], 
                  ['0002', None, 'backlog', '2019-02-15', '2019-02-25'],
                  ['0002', None, 'backlog', '2019-02-15', '2019-02-25'],
                  ['0002', None, 'backlog', '2019-02-15', '2019-02-25'],
                  ['0002', 'backlog', 'complete', '2019-02-25', '9999-12-31'],
                  ['0003', None, 'backlog', '2020-01-15', '2020-01-31'],
                  ['0003', None, 'backlog', '2020-01-15', '2020-01-31'],
                  ['0003', None, 'backlog', '2020-01-15', '2020-01-31'],
                  ['0003', 'backlog', 'modified', '2020-01-31', '2020-02-05'],
                  ['0003', 'modified', 'qe_backlog', '2020-02-05', '2020-02-20'],
                  ['0003', 'qe_backlog', 'verified', '2020-02-20', '9999-12-31']] ,
                 columns=['id', 'old_state', 'new_state', 'start_dttm', 'end_dttm'])

приводит к

      id   old_state   new_state  start_dttm    end_dttm
0   0001        None     backlog  2020-01-15  2020-01-31
1   0001     backlog    complete  2020-01-31  9999-12-31
2   0001     backlog    complete  2020-01-31  9999-12-31
3   0002        None     backlog  2019-02-15  2019-02-25
4   0002        None     backlog  2019-02-15  2019-02-25
5   0002        None     backlog  2019-02-15  2019-02-25
6   0002        None     backlog  2019-02-15  2019-02-25
7   0002     backlog    complete  2019-02-25  9999-12-31
8   0003        None     backlog  2020-01-15  2020-01-31
9   0003        None     backlog  2020-01-15  2020-01-31
10  0003        None     backlog  2020-01-15  2020-01-31
11  0003     backlog    modified  2020-01-31  2020-02-05
12  0003    modified  qe_backlog  2020-02-05  2020-02-20
13  0003  qe_backlog    verified  2020-02-20  9999-12-31

В конце я хотел бы получить:

id   state       backlog_dttm      completed_dttm  modified_dttm qe_backlog_dttm    verified_dttm
0001 complete     2020-01-15       2020-01-31           null            null       null 
0002 complete     2019-02-15       2019-02-25      null        null     null      null
0003 verified     2020-01-15       null            2020-01-31        2020-02-05        2020-02-20          

Пока у меня есть

d.drop_duplicates(subset=d.columns, keep='last', inplace=True)
d.set_index('id', inplace=True)

Тогда в В этот момент, пытаясь установить backlog_dttm, все перестает работать.

d2['backlog_dttm'] = d[d['old_state'].isnull() & (d['new_state'] == 'backlog')]['start_dttm']
d2 = d.loc[d['end_dttm'] == d.end_dttm.max()]
d2.loc[d2.index,'backlog_dttm'] = d[d['old_state'].isnull() & (d['new_state'] == 'backlog')]['start_dttm']
d2.loc[d2.index, 'completed_dttm'] = d[d['new_state'] == 'complete']['start_dttm']
d2.loc[d2.index, 'modified_dttm'] = d[d['new_state'] == 'modified']['start_dttm']
d2.loc[d2.index, 'qe_backlog_dttm'] = d[d['new_state'] == 'qe_backlog']['start_dttm']

Вышеуказанное приводит к SettingWithCopyWarning, но, похоже, работает. Окончательный желаемый результат должен выглядеть примерно так:

       old_state new_state  start_dttm    end_dttm backlog_dttm  \
id                                                                
0001     backlog  complete  2020-01-31  9999-12-31   2020-01-15   
0002     backlog  complete  2019-02-25  9999-12-31   2019-02-15   
0003  qe_backlog  verified  2020-02-20  9999-12-31   2020-01-15   

     completed_dttm modified_dttm qe_backlog_dttm  
id                                                 
0001     2020-01-31           NaN             NaN  
0002     2019-02-25           NaN             NaN  
0003            NaN    2020-01-31      2020-02-05

В качестве справки: это всего лишь пример, реальный набор данных основан на рабочем процессе разработки, в котором будут другие состояния, такие как ready_to_test, Verified, in_progress. , et c ... и аналогичным образом, для этих состояний также должны быть столбцы, которые необходимо заполнить, то есть Verified_dttm, read_to_test_dttm ..

Поля start_dttm и end_dttm используются для определения даты, когда была введена запись данное состояние и дата выхода из этого состояния.

Любые мысли / предложения приветствуются. -Спасибо!

Ответы [ 3 ]

2 голосов
/ 01 февраля 2020

Вы можете попробовать использовать DataFrame.groupby и DataFrame.unstack:

# find the most recent state for each id
df1 = df.groupby('id').agg({'new_state':'last'})
# find start dates for each new state by id and unstack into columns
df2 = df.groupby(['id','new_state'])['start_dttm'].agg('first').unstack()
# merge grouped dataframes together by id
df = df1.join(df2).reset_index() 

print(df)                                                                                                        
     id new_state     backlog    complete    modified  qe_backlog    verified
0  0001  complete  2020-01-15  2020-01-31         NaN         NaN         NaN
1  0002  complete  2019-02-15  2019-02-25         NaN         NaN         NaN
2  0003  verified  2020-01-15         NaN  2020-01-31  2020-02-05  2020-02-20
1 голос
/ 01 февраля 2020

Если вы просто хотите избавиться от SettingWithCopyWarning, вы можете указать индекс при добавлении столбца

d2.loc[d2.index,'backlog_dttm'] = d[d['old_state'].isnull() & (d['new_state'] == 'backlog')]['start_dttm']

Кажется, что решение взлома Кенана хорошо работает, если просто переименовать столбцы.

0 голосов
/ 01 февраля 2020

Если old_state в [None, backlog] и new_state в [backlog, completed]

Вы можете взломать решение с помощью

df[df['old_state'].isna()].assign(old_state='complete').drop('new_state', axis=1).rename(columns={'old_state': 'state', 'start_dttm': 'backlog_dttm', 'end_dttm': 'completed_dttm'})
     id     state backlog_dttm completed_dttm
0  0001  complete   2020-01-15     2020-01-31
2  0002  complete   2019-02-15     2019-02-25
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...