Перебор списков в панде DataFrame - PullRequest
0 голосов
/ 28 февраля 2019

Мои оригинальные панды DataFrame выглядит следующим образом:

df =

    Person_ID | trip_purpose | trip_start_time | trip_end_time
    -----------------------------------------------------------
         1    |    'Work'    |   05:40:00      |  05:42:00
         2    |   'School'   |   06:40:00      |  06:45:00
         1    |   'Leisure'  |   05:52:00      |  06:37:00
         1    |    'Home'    |   06:40:00      |  06:49:00  
        ...

Первый шаг: группировка по Person_ID:

df = df.groupby('Person_ID').agg(lambda x : ','.join(x).split(',')) 
# this is faster than grouping by .agg(list)

Результат группировки:

Person_ID |   trip_purpose   | trip_start_time | trip_end_time
---------------------------------------------------------------
          |    ['Work',      |   [05:40:00,    |  [05:42:00,
     1    |     'Leisure',   |    05:52:00,    |   06:37:00,
          |     'Home']      |    06:40:00]    |   06:49:00]
          |                  |                 |
     2    |   ['School']     |   [06:40:00 ]   |  [06:45:00]   
    ...

InНа следующем шаге я хочу рассчитать время, которое человек потратил на каждое занятие между поездками, и записать его в определенный столбец.Так как мои агенты начинают свой день дома, кулачная деятельность всегда "живая", что означает, что это duration_activity_1 дается первым временем начала

pd.to_timedelta(df['trip_start_time'].apply(lambda x: x[0])).

Это означает, что еслиЧеловек 1 совершает 3 поездки, у него 4 действия, потому что он / она начинает дома.

Последнее действие длится до полуночи, то есть оно рассчитывается по

pd.to_datetime("23:59:59") - pd.to_datetime(df['trip_end_time').apply(lambda x: x[-1]))

Все длительности действий между первым и последним рассчитываются путем вычитания времени начала текущей поездки за вычетом времени окончания последней поездки:

pd.to_timedelta(df['trip_start_time'].apply(lambda x: x[i])) - pd.to_timedelta(df['trip_end_time'].apply(lambda x: x[i - 1]))]

Вот чтоэто должно выглядеть так:

Person_ID |   trip_purpose   | trip_start_time | trip_end_time | duration_activity_1 | duration_activity_2 | duration_activity_3 | duration_activity_4 | ...
------------------------------------------------------------------------------------------------------------------------------------------------------------
          |    ['Work',      |   [05:40:00,    |  [05:42:00,   |                     |                     |                     |                     |  
     1    |     'Leisure',   |    05:52:00,    |   06:37:00,   |    05:40:00         |     00:10:00        |     00:03:00        |     17:14:00        |
          |     'Home']      |    06:40:00]    |   06:49:00]   |                     |                     |                     |                     |
          |                  |                 |               |                     |                     |                     |                     |
     2    |   ['School']     |   [06:40:00 ]   |  [06:45:00]   |    06:40:00         |     17:15:00        |          nan        |          nan        |
    ...

Поскольку я хочу вычислить скалярным способом, и у меня есть более одного условия, о котором я подумал numpy.select():

import numpy as np
import pandas as pd

    for i in range(maximum_number_of_activities):
        condlist = [i == 0,    # first activity
                    i == df["trip_purpose"].apply(len),    # last activity
                    (i > 0) & (i < df["trip_purpose"].apply(len))]    # other activities
        choicelist = [pd.to_timedelta(df["trip_start_time"].apply(lambda x: x[0])),    # first activity starts at midnight and ends with the first trip
                      pd.to_datetime("23:59:59") - pd.to_datetime(df["trip_end_time"].apply(lambda x: x[-1])),    # last activity starts with the last trip and ends at midnight
                      pd.to_timedelta(df["trip_start_time"].apply(lambda x: x[i])) - pd.to_timedelta(df["trip_end_time"].apply(lambda x: x[i - 1]))]    # all other activities are calculated by substracting the start time of the current trip minus the end time of the last trip
        default = np.nan
        print(pd.DataFrame(np.select(condlist=condlist,
                                     choicelist=choicelist,
                                     default=default),
                           columns=[i]))

# I'm aware that this code is not assigning it to the original DataFrame.

А вот мойпроблема: я получаю IndexError: list index out of range

Я полагаю, это как-то связано с 3-м условием в choicelist.Я полагаю, что даже если я поймаю случаи i == 0 и i == df["trip_purpose"].apply(len), я не смогу использовать индексную переменную i, потому что 3-е условие не будет выполнено?!?(Я получаю тот же результат, если я пишу choicelist непосредственно в функцию np.select.)

Можете ли вы найти решение этого или альтернативного способа получить желаемый DataFrame?Буду очень признателен за вашу помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...