Изменение формы данных Pandas, превращение нескольких строк с одним и тем же индексом, но разными значениями во множество столбцов в зависимости от частоты - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть следующая таблица в pandas

user_id idaggregate_info    num_events  num_lark_convo_events   num_meals_logged    num_breakfasts  num_lunches num_dinners num_snacks  total_activity  sleep_duration  num_activity_events num_weights num_notifs  idusermission   completed   mission_delta
0   0   406 94  20  7   2   2   2   1   4456    47738   72  0   18  1426    0   NaT
1   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   7 days 10:04:28
2   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   NaT
3   2   2088    356 32  15  6   6   1   2   41598   184113  314 1   21  967 1   8 days 00:03:05
4   2   2088    356 32  15  6   6   1   2   41598   184113  314 1   21  967 1   NaT

Некоторые user_ids имеют несколько одинаковых строк, за исключением их различных значений mission_delta.Как мне преобразовать это в одну строку для каждого идентификатора со столбцами с именами «mission_delta_1», «mission_delta_2» (их число может варьироваться, это может быть от 1 на user_id до 5 на user_id, поэтому присвоение имен должно быть повторяющимся_ и т. Д.будет выглядеть следующим образом:

user_id idaggregate_info    num_events  num_lark_convo_events   num_meals_logged    num_breakfasts  num_lunches num_dinners num_snacks  total_activity  sleep_duration  num_activity_events num_weights num_notifs  idusermission   completed   mission_delta_1 mission_delta_2
0   0   406 94  20  7   2   2   2   1   4456    47738   72  0   18  1426    0   NaT
1   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   7 days 10:04:28  NaT
2   2   2088    356 32  15  6   6   1   2   41598   184113  314 1   21  967 1   8 days 00:03:05     NaT

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

df.groupby(level=0).apply(lambda x: pd.Series(x.values.flatten()))

производит то же значение df, что и оригинал с другими метками

    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
    0   0   406 94  20  7   2   2   2   1   4456    47738   72  0   18  1426    0   NaT
    1   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   7 days 10:04:28
    2   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   NaT
    3   2   2088    356 32  15  6   6   1   2   41598   184113  314 1   21  967 1   8 days 00:03:05

Следующие опции:

result2.groupby(level=0).apply(lambda x: pd.Series(x.stack().values))

производит:

0     0         0
  1       406
  2        94
  3        20
  4         7

и

df.groupby(level=0).apply(lambda x: x.values.ravel()).apply(pd.Series)

создает исходный фрейм данных:

    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
    0   0   406 94  20  7   2   2   2   1   4456    47738   72  0   18  1426    0   NaT
    1   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   7 days 10:04:28
    2   1   1247    121 48  26  8   7   2   9   48695   37560   53  14  48  1379    1   NaT
    3   2   2088    356 32  15  6   6   1   2   41598   184113  314 1   21  967 1   8 days 00:03:05

По сути, я хочу превратить df:

id    mission_delta
0     NaT
1     1 day
1     2 days
1     1 day
2     5 days
2      NaT

в

id    mission_delta1  mission_delta_2 mission_delta_3
0     NaT     NaT        NaT
1     1 day   2 days    1 day
2     5 days   NaT      NaT

1 Ответ

0 голосов
/ 13 декабря 2018

Вы можете попробовать это;

grp = df.groupby('id')
df_res = grp['mission_delta'].apply(lambda x: pd.Series(x.values)).unstack().fillna('NaT')
df_res = df_res.rename(columns={i: 'mission_delta_{}'.format(i + 1) for i in range(len(df_res))})

print(df_res)

   mission_delta_1 mission_delta_2 mission_delta_3
id                                                
0              NaT             NaT             NaT
1            1 day          2 days           1 day
2           5 days             NaT             NaT
...