Разделить или объединить действия по дате

1

Мне нравится создавать базу данных последовательности, основанную на разных действиях (ACT), на тех же или разных датах. Как вы можете видеть, некоторые строки могут содержать значения NaN. Мне нужны последние данные для обучения модели машинного обучения по последовательностям действий.

ID  ACT1        ACT2        ACT3        ACT4        ACT5    
0   2015-08-11  2015-08-16  2015-08-16  2015-09-22  2015-08-19
1   2014-07-16  2014-07-16  2014-09-16  NaT         2014-09-12
2   2016-07-16  NaT         2017-09-16  2017-09-16  2017-12-16

Ожидаемый результат, который будет разделяться или объединяться в зависимости от значений даты, будет выглядеть следующим образом:

ID Sequence1  Sequence2  Sequence3  Sequence4  
0  ACT1       ACT2,ACT3  ACT5       ACT4
1  ACT1,ACT2  ACT5       ACT3
2  ACT1       ACT3,ACT4  ACT5

Следующий скрипт выведет строку со всей последовательностью:

df['Sequence'] = df.loc[:, cols].apply(lambda dr: ','.join(df.loc[:, cols].columns[dr.dropna().argsort()]), axis=1)

Sequence
ACT1,ACT2,ACT3,ACT5,ACT4
ACT1,ACT2,ACT5,ACT3
ACT1,ACT3,ACT4,ACT5
Теги:
merge
split
sequence

1 ответ

1
Лучший ответ

Это было сложно, но я считаю, что это сработает для вас.

from collections import defaultdict
import pandas as pd

data = {
      'ACT1': [pd.Timestamp(year=2015, month=8, day=11),
               pd.Timestamp(year=2014, month=7, day=16),
               pd.Timestamp(year=2016, month=7, day=16)],
      'ACT2': [pd.Timestamp(year=2015, month=8, day=16),
               pd.Timestamp(year=2014, month=7, day=16),
               np.nan],
      'ACT3': [pd.Timestamp(year=2015, month=8, day=16),
               pd.Timestamp(year=2014, month=9, day=16),
               pd.Timestamp(year=2017, month=9, day=16)],
      'ACT4': [pd.Timestamp(year=2015, month=9, day=22),
               np.nan, 
               pd.Timestamp(year=2017, month=9, day=16)],
      'ACT5': [pd.Timestamp(year=2015, month=8, day=19),
               pd.Timestamp(year=2014, month=9, day=12),
               pd.Timestamp(year=2017, month=12, day=16)]}

df = pd.DataFrame(data)

# Unstack so we can create groups
unstacked = df.unstack().reset_index()

# This will keep track of our sequence data
sequences = defaultdict(list)

# Here we get our groups, e.g., 'ACT1,ACT2', etc.;
# We group by date first, then by original index (0,1,2)
for i, g in unstacked.groupby([0, 'level_1']):
    sequences[i[1]].append(','.join(g.level_0))

# How many sequences (columns) we're going to need
n_seq = len(max(sequences.values(), key=len))

# Any NaTs will always shift your data to the left,
# so to speak, so we need to right pad the rows 
for k in sequences:
    while len(sequences[k]) < n_seq:
        sequences[k].append('')

# Create column labels and make new dataframe
columns = ['Sequence{}'.format(i) for i in range(1, n_seq + 1)]
print pd.DataFrame(list(sequences.values()), columns=columns)

   Sequence1  Sequence2 Sequence3 Sequence4
0       ACT1  ACT2,ACT3      ACT5      ACT4
1  ACT1,ACT2       ACT5      ACT3          
2       ACT1  ACT3,ACT4      ACT5   
  • 0
    Спасибо, что отлично сработало! Только один вопрос: что нужно изменить в сценарии, если мы не будем группировать в одни и те же даты, а сделаем его последовательным для каждого элемента в порядке столбцов по умолчанию? Так что у нас будет Sequence1 -ACT1, Sequence2 - ACT2 вместо Sequence1 ACT1, ACT2?
  • 0
    извините, что спросил вас снова.
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню