У меня есть датафрейм, который выглядит так:
>> df
index week day hour count
5 10 2 10 70
5 10 3 11 80
7 10 2 18 15
7 10 2 19 12
, где week
- неделя года, day
- день недели (0-6
) и hour
- час дня (0-23
). Однако, поскольку я планирую преобразовать это в трехмерный массив (неделя x день x час) позже, я должен включить часы, в которых нет элементов в столбце count
. Пример:
>> target_df
index week day hour count
5 10 0 0 0
5 10 0 1 0
...
5 10 2 10 70
5 10 2 11 0
...
7 10 0 0 0
...
...
и так далее. Что я делаю, это создаю фиктивный фрейм данных, содержащий все возможные комбинации индекс-неделя-день-час (в основном target_df
без столбца count
):
>> dummy_df
index week day hour
5 10 0 0
5 10 0 1
...
5 10 2 10
5 10 2 11
...
7 10 0 0
...
...
, а затем с помощью
target_df = pd.merge(df, dummy_df, on=['index','week','day','hour'], how='outer').fillna(0)
Это отлично работает для небольших наборов данных, но я работаю с большим количеством строк. С делом, над которым я сейчас работаю, я получаю 82M строк для dummy_df
и target_df
, и это мучительно медленно.
РЕДАКТИРОВАТЬ : Самая медленная часть на самом деле создает dummy_df
!!! Я могу сгенерировать отдельные списки, но объединение их в фрейм данных панд - самая медленная часть.
num_weeks = len(week_list)
num_idxs = len(df['index'].unique())
print('creating dummies')
_dummy_idxs = list(itertools.chain.from_iterable(
itertools.repeat(x, 24*7*num_weeks) for x in df['index'].unique()))
print('\t_dummy_idxs')
_dummy_weeks = list(itertools.chain.from_iterable(
itertools.repeat(x, 24*7) for x in week_list)) * num_idxs
print('\t_dummy_weeks')
_dummy_days = list(itertools.chain.from_iterable(
itertools.repeat(x, 24) for x in range(0,7))) * num_weeks * num_idxs
print('\t_dummy_days')
_dummy_hours = list(range(0,24)) * 7 * num_weeks * num_idxs
print('\t_dummy_hours')
print('Creating dummy_hour_df with {0} rows...'.format(len(_dummy_hours)))
# the part below takes the longest time
dummy_hour_df = pd.DataFrame({'index': _dummy_idxs, 'week': _dummy_weeks, 'day': _dummy_days, 'hour': _dummy_hours})
print('dummy_hour_df completed')
Есть ли более быстрый способ сделать это?