Ниже приведен код, позволяющий точно воспроизвести проблему. По сути это приведет к увеличению вашей памяти с 90 МБ или около того до 5 ГБ за считанные секунды, если вы не убьете ее. С потреблением памяти также придет ограниченный процессор.
Память также будет сохраняться после выхода из функции сортировки.
Похоже, что эта проблема появляется только в том случае, если я начинаю с большого основного кадра данных, делаю его на части и затем выполняю сортировку. Если я построю кучу независимых фреймов данных; этого не происходит.
def test_sorting(df_list):
counter = 0
total = len(df_list)
for i in range(0,total):
df_list[i].sort_index(inplace=True)
import pandas as pd
import numpy as np
from math import floor
def make_master_df(rows = 250000):
groups = 5
df = pd.DataFrame(np.random.randint(0,100,size=(rows, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
df["timestep"] = pd.Series([floor(x / groups) for x in range(0,rows)])
df["id"] = pd.Series([ x % groups for x in range(0,rows)])
df = df.set_index(["timestep", "id"]).sort_index()
return df
def create_train_test_windows(df, train_size, test_size, slide_size, include_history = True, second_index=False):
n = train_size + test_size
size_multiplier = 1
if(second_index):
size_multiplier = df.index.levels[1].size
n = n * size_multiplier
list_df = None
if(include_history):
df.sort_index(ascending=True, inplace=True)
list_df = [df[:-(i + n)] for i in range(0, df.shape[0], slide_size * size_multiplier)]
list_df.insert(0,df[:])
list_df = list_df[::-1]
else:
raise Exception("excluding history currently not supported.")
list_df = [x for x in list_df if x.shape[0] >= n]
return list_df
master_df = make_master_df()
list_df = create_train_test_windows(master_df, 500, 20, 20, include_history=True, second_index=True)
И это в конечном итоге взорвет вашу память во время выполнения, и эта память будет удерживаться после завершения выполнения.
test_sorting(list_df)
ПРИМЕЧАНИЯ:
Я заметил, что каждый из нарезанных фреймов данных поддерживал полный размер уровня индекса для первого индекса (временные шаги).
Я заставил использовать gc.collect () на каждом шаге, чтобы попытаться проявить агрессию. (вообще не работал).
Я протестировал как автономный скрипт на Python, так и в блокноте IPython с теми же результатами.
Мое лучшее предположение заключается в том, что нарезанные кадры данных на самом деле не являются правильным срезом; они приносят с собой изрядное количество багажа, на который есть ссылки в другом месте.
Любые идеи и помощь приветствуются!