2016-10-31 3 views
1

У меня есть следующий dataframe:Условный засыпки колонн панд

 DATE  ID  STATUS 
0 2014-01-01 1 INPROGRESS 
1 2013-03-01 1  ENDED 
2 2015-05-01 2 INPROGRESS 
3 2012-05-01 1  STARTED 
4 2011-05-01 2  STARTED 
5 2011-03-01 3  STARTED 
6 2011-04-01 3  ENDED 
7 2011-06-01 3 INPROGRESS 
8 2011-09-01 3  STARTED 

здесь код, чтобы построить его:

>>> df1 = pd.DataFrame(columns=["DATE", "ID", "STATUS"]) 
>>> df1["DATE"] = ['2014-01-01', '2013-03-01', '2015-05-01', '2012-05-01', '2011-05-01', '2011-03-01', '2011-04-01', '2011-06-01', '2011-09-01'] 
>>> df1["ID"] = [1,1,2,1,2,3,3,3,3] 
>>> df1["STATUS"] = ['INPROGRESS', 'ENDED', 'INPROGRESS', 'STARTED', 'STARTED', 'STARTED','ENDED', 'INPROGRESS', 'STARTED'] 

для каждой группы идентификаторов столбец состояния представляет собой задачу, которая может быть:

НАЧАЛО, ИНТЕРЕСНО ИЛИ ЗАКРЫТЬ

в этом точном срочном заказе (НАЧАЛО не должно пришел после ENDED и т.п ..). не

Группировка по идентификатору и сортировать по дате я получаю по ID 3:

df1.sort_values('DATE')[df1['ID']==3] 

    DATE  ID  STATUS 
5 2011-03-01 3  STARTED 
6 2011-04-01 3  ENDED 
7 2011-06-01 3 INPROGRESS 
8 2011-09-01 3  STARTED 

Нет, я бы нужно «FIX» столбец статуса, чтобы следовать в порядке, установленном выше на основе последнего статуса. Для ID 3 запускается, так что все должно быть засыпаны в запущенном состоянии, как следовать за последним статус:

 DATE  ID  STATUS 
5 2011-03-01 3  STARTED 
6 2011-04-01 3  STARTED 
7 2011-06-01 3  STARTED 
8 2011-09-01 3  STARTED 

Для ID 1:

df1.sort_values('DATE')[df1['ID']==1] 
    DATE ID  STATUS 
3 2012-05-01 1  STARTED 
1 2013-03-01 1  ENDED 
0 2014-01-01 1 INPROGRESS 

я бы в конечном итоге, последние два состояния INPROGRESS и оставьте первый, как НАЧАЛО, как:

df1.sort_values('DATE')[df1['ID']==1] 
    DATE ID  STATUS 
3 2012-05-01 1  STARTED 
1 2013-03-01 1 INPROGRESS 
0 2014-01-01 1 INPROGRESS 

ID 2 имеет правильный порядок.

Любая идея, как я могу это сделать с помощью панд? Я пытаюсь группировать по ID, и я думаю о обратной засыпке, основываясь на последнем статусе, но я не знаю, как я мог бы остановить залив в нужный момент.

спасибо!

ответ

2

Классический способ состоит в том, чтобы забыть, что ваши статусы являются ярлыками: вместо этого рассматривайте их как строго возрастающие числа, например, начатые 1, в процессе 2 и закончились 3. С таким столбцом вы можете теперь проверить монотонность этих чисел для каждой группы, затем засыпьте, пока не увидите нарушение монотонности.

Подготовьте dataframe:

keymapping = {'STARTED':0, 'INPROGRESS':1, 'ENDED':2} 
df['STATUS_ID'] = df.STATUS.map(keymapping) 
df.set_index(['ID', 'DATE'], inplace=True) 
df.sort_index(inplace=True) 

Теперь группа по ID и использовать transform, чтобы получить последнее значение каждой группы распространения по всей индексу, так что вы можете назначить его на dataframe как новый столбец :

df['STATUS_LAST'] = df.groupby(level=0, as_index=False).STATUS_ID.transform('last') 

df 
Out[63]: 
        STATUS STATUS_ID STATUS_LAST 
ID DATE           
1 2012-05-01  STARTED   0   1 
    2013-03-01  ENDED   2   1 
    2014-01-01 INPROGRESS   1   1 
2 2011-05-01  STARTED   0   1 
    2015-05-01 INPROGRESS   1   1 
3 2011-03-01  STARTED   0   0 
    2011-04-01  ENDED   2   0 
    2011-06-01 INPROGRESS   1   0 
    2011-09-01  STARTED   0   0 

Наконец, примените засыпка, используя все большее однообразие STATUS_ID против последнего, т.е. каждое значение STATUS_ID справедливо, когда, если меньше или равно STATUS_LAST:

df.STATUS_ID = df.STATUS_ID.where(df.STATUS_ID <= df.STATUS_LAST, df.STATUS_LAST) 
df.STATUS_ID 
Out[65]: 
ID DATE  
1 2012-05-01 0 
    2013-03-01 1 
    2014-01-01 1 
2 2011-05-01 0 
    2015-05-01 1 
3 2011-03-01 0 
    2011-04-01 0 
    2011-06-01 0 
    2011-09-01 0 

Reverse карта его на этикетках и присвоить его STATUS:

df.STATUS_ID.map({v:k for k,v in keymapping.items()}) 
Out[66]: 
ID DATE  
1 2012-05-01  STARTED 
    2013-03-01 INPROGRESS 
    2014-01-01 INPROGRESS 
2 2011-05-01  STARTED 
    2015-05-01 INPROGRESS 
3 2011-03-01  STARTED 
    2011-04-01  STARTED 
    2011-06-01  STARTED 
    2011-09-01  STARTED 
Name: STATUS_ID, dtype: object 
Смежные вопросы