Набор данных:
Ниже набор данных должен копировать набор данных расписания для туристической компании (например, маршруты на поезде, автобусе или самолете и т. Д.)
df = pd.DataFrame({'operator': ['op_a', 'op_a', 'op_a', 'op_a', 'op_b', 'op_b', 'op_b', 'op_b', 'op_c', 'op_c', 'op_c', 'op_c', 'op_d', 'op_d'],
'from': ['a', 'a', 'a', 'a', 'c', 'c', 'c', 'c', 'a', 'a', 'a', 'a', 'x', 'x'],
'to': ['b', 'b', 'b', 'b', 'd', 'd', 'd', 'd', 'b', 'b', 'b', 'b', 'y', 'y'],
'valid_from': ['13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '15/02/2019', '15/02/2019', '15/02/2019', '15/02/2019', '20/05/2019', '21/05/2019'],
'valid_to': ['20/11/2018', '20/11/2018', '19/11/2018', '19/11/2018', '19/11/2018', '19/11/2018', '21/11/2018', '21/11/2018', '21/02/2019', '21/02/2019', '20/02/2019', '20/02/2019', '30/05/2019', '29/05/2019'],
'day_of_week': ['0101010', '0100010', '0111100', '1101100', '0101010', '0100010', '0111100', '1101100', '0001101', '1110000', '0000000', '0000001', '1000000', '1000001']})
print(df)
operator
- управляющая компания, например, ABC Airlines, DEF Train Company
from
- отправляется, например, из Лондона, Нью-Йорка, Нарнии
to
- пункт назначения, например, Париж
valid_from
- начало диапазона дат (может быть любой день недели), в котором для оператора доступен маршрут для покупки, например: 2019-11-01
valid_to
- конец диапазона дат (можетбыть любым днем недели), где маршрут доступен для покупки для оператора, например, 2019-11-12
day_of_week
- двоичный файл, представляющий доступность для ВС до Сб, например, 0101010
означает, что маршрут доступен в понедельник, среду,и пт в диапазоне дат
Обязательно:
Выходной набор данных, который преобразует диапазон дат в отдельные даты и их доступность определяется на основе поля day_of_week
.Основная цель - получить чистый набор данных, который затем можно загрузить в Таблицу, чтобы затем создать отчет, который бы легко отображал доступность маршрута.
Желаемый результат:
dfout = pd.DataFrame({'operator': ['op_a', 'op_a', 'op_a', 'op_a', 'op_a', 'op_a', 'op_a'], 'from': ['a', 'a', 'a', 'a', 'a', 'a', 'a'], 'to': ['b', 'b', 'b', 'b', 'b', 'b', 'b'], 'date': ['13/11/2018', '14/11/2018', '15/11/2018', '16/11/2018', '17/11/2018', '18/11/2018', '19/11/2018'], 'available': [1, 1, 1, 1, 0, 1, 1]})
print(dfout)
Таким образом, это будет вывод для op_a
для маршрута от a
до b
для диапазона дат * от 1044 * до 2018-11-19
.
Набор данных выглядит странно.Диапазоны дат могут быть довольно случайными, но day_of_week
всегда будет отображать доступность для дней недели в этом диапазоне дат.Некоторые из одних и тех же диапазонов дат могут даже иметь различные двоичные комбинации day_of_week
, но, по сути, если в какой-то момент day_of_week
указывает на доступность для данного диапазона дат, маршрута и оператора, то он будет считаться доступным для даты.
То, что я пытался сделать:
Использование следующего для справки: Панды: декомпрессировать диапазон дат до отдельных дат
import pandas as pd
df = pd.DataFrame({'operator': ['op_a', 'op_a', 'op_a', 'op_a', 'op_b', 'op_b', 'op_b', 'op_b', 'op_c', 'op_c', 'op_c', 'op_c', 'op_d', 'op_d'],
'from': ['a', 'a', 'a', 'a', 'c', 'c', 'c', 'c', 'a', 'a', 'a', 'a', 'x', 'x'],
'to': ['b', 'b', 'b', 'b', 'd', 'd', 'd', 'd', 'b', 'b', 'b', 'b', 'y', 'y'],
'valid_from': ['13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '13/11/2018', '15/02/2019', '15/02/2019', '15/02/2019', '15/02/2019', '20/05/2019', '21/05/2019'],
'valid_to': ['20/11/2018', '20/11/2018', '19/11/2018', '19/11/2018', '19/11/2018', '19/11/2018', '21/11/2018', '21/11/2018', '21/02/2019', '21/02/2019', '20/02/2019', '20/02/2019', '30/05/2019', '29/05/2019'],
'day_of_week': ['0101010', '0100010', '0111100', '1101100', '0101010', '0100010', '0111100', '1101100', '0001101', '1110000', '0000000', '0000001', '1000000', '1000001']})
df.set_index(['operator', 'from','to'], inplace=True)
df['valid_from'] = pd.to_datetime(df['valid_from'])
df['valid_to'] = pd.to_datetime(df['valid_to'])
df['row'] = range(len(df))
starts = df[['valid_from', 'day_of_week', 'row']].rename(columns={'valid_from': 'date'})
ends = df[['valid_to', 'day_of_week', 'row']].rename(columns={'valid_to':'date'})
df_decomp = pd.concat([starts, ends])
df_decomp = df_decomp.set_index('row', append=True)
df_decomp.sort_index()
df_decomp = df_decomp.groupby(level=[0,1,2,3]).apply(lambda x: x.set_index('date').resample('D').fillna(method='pad'))
Результат выглядит многообещающим.Мои последние мысли:
- добавить столбец
weekday
, который возвращает день недели date
, начиная с Sunday
как 0
- и добавляя
available
столбец, который возвращает двоичное значение в day_of_week
, используя weekday
в качестве индекса позиции - , наконец, чтобы каким-то образом удалить дубликаты
operator
, from
и to
и сохранить available
, чтоиметь 1
и отбрасывать те, которые 0
или если * * нет 1082 * для этих operators
'/ from
' / to
, то оставьте доступным 0
...
безумие ... извиняюсь за многословность, и я надеюсь, что у меня есть смысл.Любая помощь по этому вопросу будет принята с благодарностью.
Редактировать:
- Обновлена часть "Что я пытался сделать" выше.
- Обновлен набор данных, теперь он включает в себя немного большее разнообразие дат (все тот же набор данных, только что скорректированный
valid_to
даты)