Я анализирую набор событий, каждое из которых имеет метку времени начала, начала и окончания. Я пытаюсь суммировать число одновременных событий каждого времени, которое происходит в течение временного диапазона.
Рассмотрим набор данных ниже, перечисляя события N1-N4, каждое из которых имеет перекрывающиеся диапазоны:
>>> data = {
... 'name' : [ 'N1', 'N2', 'N3', 'N4', 'N1', 'N2', 'N7'],
... 'start_dt_str' : ['01-01-2020', '01-03-2020', '01-01-2020', '01-01-2020', '01-03-2020', '01-04-2020','01-10-2020'],
... 'end_dt_str' : ['01-03-2020', '01-05-2020', '01-05-2020', '01-02-2020', '01-04-2020', '01-05-2020', '01-11-2020']
... }
>>> df = pd.DataFrame(data)
>>> df['start_dt'] = pd.to_datetime(df['start_dt_str'])
>>> df['end_dt'] = pd.to_datetime(df['end_dt_str'])
>>> del df['start_dt_str']
>>> del df['end_dt_str']
>>> df
name start_dt end_dt
0 N1 2020-01-01 2020-01-03
1 N2 2020-01-03 2020-01-05
2 N3 2020-01-01 2020-01-05
3 N4 2020-01-01 2020-01-02
4 N1 2020-01-03 2020-01-04
5 N2 2020-01-04 2020-01-05
6 N7 2020-01-10 2020-01-11
Моя цель состоит в том, чтобы составить эту сводную информацию о количестве одновременных событий по типу для каждой даты в диапазоне. Это будет правильный ответ:
N1 N2 N3 N4 N7
2020-01-01 1 0 1 1 0
2020-01-02 1 0 1 1 0
2020-01-03 2 1 1 0 0
2020-01-04 1 2 1 0 0
2020-01-05 1 2 0 0 0
2020-01-06 0 0 0 0 0
2020-01-07 0 0 0 0 0
2020-01-08 0 0 0 0 0
2020-01-09 0 0 0 0 0
2020-01-10 0 0 0 0 1
2020-01-11 0 0 0 0 1
Обратите внимание, что в столбцах start_dt и end_dt есть повторяющиеся даты.
Также обратите внимание, что решение должно обеспечивать возможность повторной выборки данных, чтобы заполнить отсутствующие даты строками, содержащими все нули. В этом примере дата 01-09 не отображается как дата начала или окончания, но должна присутствовать в выходных данных. В общем случае я sh смогу сделать повторную выборку для выбора любых произвольных интервалов.
Для простоты объяснения проблемы и отчетный период, и данные имеют дневную точность в наборе данных выше , В фактическом наборе данных start_dt и end_dt с точностью до миллисекунды (но все еще содержат дубликаты), и отчетный период может быть часами, днями, неделями и т. Д. c.
Также обратите внимание, что в данных, поэтому для создания ряда дата-время требуется повторная выборка. (IE, хотя данные с точностью до миллисекунды, целых дней не хватает).
Я пробовал несколько подходов, которые НЕ работают. Во-первых, мне показалось, что это будет просто, я попробовал:
df.set_index(['name','start_dt']).groupby('name').resample('D',level='start_dt').ffill()
ValueError: Upsampling from level= or on= selection is not supported, use .set_index(...) to explicitly set index to datetime-like
, что приводит к , эта pandas проблема в отношении повышения дискретизации открыта и предоставляет некоторые обходные пути. К сожалению, мы не можем использовать только start_dt (или end_dt) в качестве индекса, потому что он не уникален:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/resample.py", line 453, in pad
return self._upsample("pad", limit=limit)
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/resample.py", line 1095, in _upsample
res_index, method=method, limit=limit, fill_value=fill_value
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/util/_decorators.py", line 227, in wrapper
return func(*args, **kwargs)
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/frame.py", line 3856, in reindex
return super().reindex(**kwargs)
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/generic.py", line 4544, in reindex
axes, level, limit, tolerance, method, fill_value, copy
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/frame.py", line 3744, in _reindex_axes
index, method, copy, level, fill_value, limit, tolerance
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/frame.py", line 3760, in _reindex_index
new_index, method=method, level=level, limit=limit, tolerance=tolerance
File "/home/dcowden/envs/analysis-env/lib/python3.6/site-packages/pandas/core/indexes/base.py", line 3149, in reindex
"cannot reindex a non-unique index "
ValueError: cannot reindex a non-unique index with a method or limit
Этот вопрос , который похож на мою проблему, но не заполняет все даты в диапазоне для каждого типа события:
>>> df.set_index('start_dt').groupby('name').resample('D').asfreq()
name end_dt
name start_dt
N1 2020-01-01 N1 2020-01-03
2020-01-02 NaN NaT
2020-01-03 N1 2020-01-04
N2 2020-01-03 N2 2020-01-05
2020-01-04 N2 2020-01-05
N3 2020-01-01 N3 2020-01-05
N4 2020-01-01 N4 2020-01-02
Это решение показалось многообещающим, но и не совсем то, что мне нужно. По сути, он ищет одно событие в пределах диапазона, но не учитывает общее число в процессе. Хотя использование IntervalIndex кажется хорошим началом.
Я чувствую, что это должно быть довольно легко, но, очевидно, мой pandas foo крайне неадекватен.
Помощь очень ценится!
РЕДАКТИРОВАТЬ: