Панды - преобразование каждого часа продолжительности события в отдельную строку - PullRequest
2 голосов
/ 07 апреля 2019

Пример, начинающийся с df:

import pandas as pd
df = pd.DataFrame({'event_id': ['123', '456'], 
                   'date': ['2018-01-01', '2018-01-01'], 
                   'start_hour' : ['10', '13'],
                   'duration' : ['1.5', '3']})
df

  event_id        date start_hour duration
0      123  2018-01-01         10      1.5
1      456  2018-01-01         13        3

Необходимым выводом является длинный df, в котором каждый час события имеет ряд. Длительности, которые не являются целым числом, должны быть округлены до следующего целого числа (например, 1,25 должно идти до 2)

Пример:

result_df = pd.DataFrame({'event_id': ['123', '123', '456', '456', '456'], 
                   'date': ['2018-01-01', '2018-01-01', '2018-01-01', '2018-01-01', '2018-01-01'], 
                   'hour' : ['10', '11', '13', '14', '15']})

result_df

  event_id        date hour
0      123  2018-01-01   10
1      123  2018-01-01   11
2      456  2018-01-01   13
3      456  2018-01-01   14
4      456  2018-01-01   15

Ответы [ 2 ]

4 голосов
/ 07 апреля 2019

Использование np.repeat и cumcount

df = pd.DataFrame({col: np.repeat(df[col], np.ceil(df.duration))) for col in df.columns})

df['start_hour'] += df.groupby('event_id').start_hour.cumcount()

Выходы

    event_id    date        start_hour  
0   123         2018-01-01  10         
0   123         2018-01-01  11         
1   456         2018-01-01  13         
1   456         2018-01-01  14         
1   456         2018-01-01  15         

Все это предполагает, что у вас есть числа , а не строки для столбцов start_hour и duration. В предоставленном вами MCVE у вас есть строки. Если это так, сначала сделайте их числами, используя

df['duration'] = pd.to_numeric(df['duration'])
0 голосов
/ 07 апреля 2019

Принятый ответ неверен. TO требует:

Длительности, которые не являются целым числом, должны быть округлены до следующего целого числа (например, 1,25 должно идти до 2)

Но df.duration.round(0) для 1.25 равно 1, а не 2.

Мне еще не разрешено комментировать. Поэтому я публикую это как новый ответ.

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