Я ищу эффективный способ обработки следующих данных в пандах.
У меня есть фрейм данных, содержащий несколько сотен тысяч начальных и конечных временных отметок:
data_df
start_ts end_ts
0 2019-06-10 12:00:00+00:00 2019-06-10 22:30:00+00:00
1 2019-06-11 12:00:00+00:00 2019-06-11 13:30:00+00:00
2 2019-06-11 14:00:00+00:00 2019-06-11 19:00:00+00:00
3 2019-06-14 12:00:00+00:00 2019-06-14 18:30:00+00:00
4 2019-06-10 12:00:00+00:00 2019-06-10 21:30:00+00:00
5 2019-06-11 12:00:00+00:00 2019-06-11 18:30:00+00:00
...
У меня также естьнабор помеченных временных бинов (tp1
- tp10
).Существует 10 лотков каждый день, но время этих лотков может меняться в зависимости от дня (например, tp1
может быть с 00:00 до 01:30 в один день, а затем с 00:00 до 01:45 в другой).день).Каждый обрабатываемый набор данных имеет 7 дней, по 10 временных периодов в день, поэтому набор диапазонов имеет размер 70 и выглядит следующим образом:
labeled_bins_df
start_range end_range label
0 2019-06-10 00:00:00+00:00 2019-06-10 04:30:00+00:00 tp1
1 2019-06-10 04:30:00+00:00 2019-06-10 09:45:00+00:00 tp2
2 2019-06-10 09:45:00+00:00 2019-06-10 12:30:00+00:00 tp3
...
Мне нужна таблица с оригиналомdata_df
данных, но с дополнительными столбцами, от tp1
до tp10
, с количеством минут в каждой строке:
timed_bins
start_ts end_ts tp1 tp2 tp3 tp4 ...
0 2019-06-10 12:00:00+00:00 2019-06-10 22:30:00+00:00 0 0 30 120 ...
1 2019-06-11 12:00:00+00:00 2019-06-11 13:30:00+00:00 0 45 45 0 ...
В настоящее время я делаю это наивно, перебираю строки и ищуЯчейки каждой строки данных, и, как вы можете себе представить, это довольно медленно.Есть ли какие-нибудь панды-фу, которые могут быть выполнены для такого типа биннинга по диапазонам даты и времени?
РЕДАКТИРОВАТЬ: мысль, которая может помочь мыслить в новом направлении.Если бы я конвертировал все свои метки времени (как в моих данных, так и в помеченных бинах) в метки времени Unix (секунды с 1 января 1970 года), то это было бы вопросом объединения / суммирования на основе целочисленных диапазонов, а не дат,Затем получилось бы количество секунд в каждой ячейке, просто разделив на 60, и я получил свои минуты в каждой ячейке.Это устраняет все опасения по поводу границ дат и т. Д.
РЕДАКТИРОВАТЬ 2: В соответствии с запросом, здесь представлен набор упрощенных выборочных данных с использованием трех разных временных интервалов.Я специально сделал один из образцов данных (второй ряд) за 2 дня.Кроме того, есть result_df
, который показывает ожидаемый результат.
data_samples = [
{'start_ts': '2019-06-10T12:00:00+0000', 'end_ts': '2019-06-10T22:30:00+0000'},
{'start_ts': '2019-06-10T22:00:00+0000', 'end_ts': '2019-06-11T05:30:00+0000'},
{'start_ts': '2019-06-10T10:00:00+0000', 'end_ts': '2019-06-10T14:15:00+0000'},
{'start_ts': '2019-06-12T08:07:00+0000', 'end_ts': '2019-06-12T18:22:00+0000'},
{'start_ts': '2019-06-11T14:03:00+0000', 'end_ts': '2019-06-11T15:30:00+0000'},
{'start_ts': '2019-06-11T02:33:00+0000', 'end_ts': '2019-06-11T10:31:00+0000'}
]
data_set = [{
'start_ts': datetime.datetime.strptime(x['start_ts'], '%Y-%m-%dT%H:%M:%S%z'),
'end_ts': datetime.datetime.strptime(x['end_ts'], '%Y-%m-%dT%H:%M:%S%z')} for x in data_samples]
data_df = pd.DataFrame(data_set)[['start_ts', 'end_ts']]
time_bin_samples = [
{'start_ts': '2019-06-10T00:00:00+0000', 'end_ts': '2019-06-10T08:15:00+0000', 'label': 't1'},
{'start_ts': '2019-06-10T08:15:00+0000', 'end_ts': '2019-06-10T18:00:00+0000', 'label': 't2'},
{'start_ts': '2019-06-10T18:00:00+0000', 'end_ts': '2019-06-11T00:00:00+0000', 'label': 't3'},
{'start_ts': '2019-06-11T00:00:00+0000', 'end_ts': '2019-06-11T09:00:00+0000', 'label': 't1'},
{'start_ts': '2019-06-11T09:00:00+0000', 'end_ts': '2019-06-11T19:15:00+0000', 'label': 't2'},
{'start_ts': '2019-06-11T19:15:00+0000', 'end_ts': '2019-06-12T00:00:00+0000', 'label': 't3'},
{'start_ts': '2019-06-12T00:00:00+0000', 'end_ts': '2019-06-12T10:30:00+0000', 'label': 't1'},
{'start_ts': '2019-06-12T10:30:00+0000', 'end_ts': '2019-06-12T12:00:00+0000', 'label': 't2'},
{'start_ts': '2019-06-12T12:00:00+0000', 'end_ts': '2019-06-13T00:00:00+0000', 'label': 't3'},
]
time_bin_set = [{
'start_ts': datetime.datetime.strptime(x['start_ts'], '%Y-%m-%dT%H:%M:%S%z'),
'end_ts': datetime.datetime.strptime(x['end_ts'], '%Y-%m-%dT%H:%M:%S%z'),
'label': x['label']} for x in time_bin_samples
]
time_bin_df = pd.DataFrame(time_bin_set)[['start_ts', 'end_ts', 'label']]
result_set = [
{'t1': 0, 't2': 360, 't3': 270},
{'t1': 330, 't2': 0, 't3': 120},
{'t1': 0, 't2': 255, 't3': 0},
{'t1': 143, 't2': 90, 't3': 382},
{'t1': 0, 't2': 87, 't3': 0},
{'t1': 387, 't2': 91, 't3': 0}
]
result_df = pd.DataFrame(result_set)