Сводка:
Я хочу расположить временные ряды кодов (большой набор данных), которые представляют начало и конец действий, в диаграмме Ганта, поэтому мне нужно перегруппировать их в Задачу (имя ), Столбцы Start (время) и Fini sh (время). Тем не менее, я могу пока делать это очень медленно, перебирая по каждой строке букву a для l oop :(
(я пробовал groupby и pivot, но я просто не * gr asp это хорошо пока достаточно, чтобы заставить их делать то, что я хочу.)
Ключ
У меня есть словарь 'key' / df с start_code , end_code и действие метка . Упрощенный пример:
import pandas as pd
code_key_cols = ["start_code", "end_code", "label"]
code_key = [[1, 2, "a"],
[3, 4, "b"],
[5, 6, "c"],
[7, 8, "d"]]
code_df = pd.DataFrame(code_key, columns=code_key_cols)
Out[]: start_code end_code label
0 1 2 a
1 3 4 b
2 5 6 c
3 7 8 d
Данные
Тогда у меня есть набор данных, который представляет собой просто временной ряд, когда эти коды. Я хочу организовать их таким образом, чтобы построить график Ганта. Для графика это означает наличие столбца задача , начало , fini sh.
( Просто создаем поддельные данные здесь, например, имитируя поведение реальных данных, когда один и тот же тип действия не может происходить дважды параллельно, только одновременно)
from random import shuffle
data = []
for i in range(3000):
start_codes = [x for x in code_df.iloc[:, 0]]
end_codes = [x for x in code_df.iloc[:, 1]]
shuffle(start_codes)
shuffle(end_codes)
[data.append(x) for x in start_codes]
[data.append(x) for x in end_codes]
data_cols = ["code", "time"]
data_df = pd.DataFrame()
data_df['code'] = data
data_df['time'] = pd.date_range(start="19700101", periods=len(data))
print(data_df.head())
code time
0 3 1970-01-01
1 1 1970-01-02
2 7 1970-01-03
3 5 1970-01-04
4 2 1970-01-05
Моя попытка:
Я могу сделать это, но только очень медленно, итерация строка за строкой! Я уверен, что pandas имеет более эффективный способ сделать это. Как бы вы это сделали? Вот как я это сделал, но с df 12K строк это занимает более 13 с: (
import numpy as np
lst = []
for _, code_row in code_df.iterrows():
begin = True
task = np.nan
start = np.nan
finish = np.nan
for _, data_row in data_df.iterrows():
if begin:
if code_row['start_code'] == data_row['code']:
task = code_row.label
start = data_row.time
begin = False
else:
if code_row['end_code'] == data_row['code']:
finish = data_row.time
begin = True
lst.append([task, start, finish])
df3 = pd.DataFrame(data=lst, columns=["Task", 'Start', 'Finish'])
Output
Для контекста я покажу цель, построив диаграмму Ганта с следующий код ( изменение для i в диапазоне выше с 3000 на 10 для упрощения).
import plotly.figure_factory as ff
import plotly.io as pio
pio.renderers.default = "browser"
fig = ff.create_gantt(df3, group_tasks=True)
fig.show()
кстати, если вы прочитали это далеко, спасибо очень за ваше время! :) 1048 *