У меня есть dataframe, который имеет более 400K строк и несколько сотен столбцов, которые я решил прочитать с кусками, потому что он не вписывается в Memory и дает мне MemoryError.
Мне удалось прочитать его в кусках так:
x = pd.read_csv('Training.csv', chunksize=10000)
и после этого я могу получить каждый из кусков, сделав это:
a = x.get_chunk()
b = x.get_chunk()
и т.д. и т.д., делают это более 40 раз, что, очевидно, является медленной и плохой практикой программирования.
Когда я пытаюсь сделать следующее в попытке создать цикл, который может сохранить каждый кусок в dataframe и как-то объединить их:
for x in pd.read_csv('Training.csv', chunksize=500):
x.get_chunk()
Я получил:
AttributeError: 'DataFrame' object has no attribute 'get_chunk'
Какой самый простой способ я могу прочитать в своем файле и объединить все мои куски во время импорта?
Кроме того, как мне сделать дальнейшие манипуляции с моим набором данных, чтобы избежать проблем с ошибками памяти (в частности, вменять нулевые значения, стандартизировать/нормализовать фрейм данных, а затем запустить модели обучения на компьютере с помощью scikit learn?
Когда вы указываете chunksize в вызове pandas.read_csv, вы возвращаете объект pandas.io.parsers.TextFileReader, а не DataFrame. Попробуйте это, чтобы пройти через куски:
reader = pd.read_csv('Training.csv',chunksize=500)
for chunk in reader:
print(type(chunk)) # chunk is a dataframe
Или возьмите все куски (что, вероятно, не решит вашу проблему!):
reader = pd.read_csv('Training.csv',chunksize=500)
chunks = [chunk for chunk in reader] # list of DataFrames
В зависимости от того, что находится в вашем наборе данных, отличный способ уменьшить использование памяти - это определить столбцы, которые можно преобразовать в категориальные данные. Любой столбец, где число различных значений намного меньше, чем число строк, является кандидатом для этого. Предположим, что столбец содержит некоторый статус с ограниченными значениями (например, "Открыть", "Закрыто", "В режиме ожидания"):
chunk['Status'] = chunk.assign(Status=lambda x: pd.Categorical(x['Status']))
Теперь будет сохранено целое число для каждой строки, а DataFrame будет содержать сопоставление (например, 0 = "Открыть", 1 = "Закрыто и т.д.")
Вы также должны посмотреть, являются ли какие-либо из ваших столбцов данных избыточными (они фактически содержат одну и ту же информацию), если они удалены. Я видел электронные таблицы, содержащие даты, где люди генерировали столбцы в течение года, недели, дня, когда им было легче работать. Избавься от них!
pd.read_csv
не возвращает итерацию, поэтому циклическое повторение не имеет смысла. Я достаточно о не знаюpandas
или методы чтения куска, но в зависимости от того, чтоget_chunk
делает , когда вы запрашиваете следующий фрагмент после последнего вы нужен ,if
илиtry
/ заexcept
заявления , чтобы проверить , следует ли итерация остановить. Очевидно, вы получите те же проблемы с памятью, если просто объедините все фрагменты в один большой DataFrame. Метод чанков предназначен для случаев, когда вы выполняете обработку на своих меньших чанках, то есть чанки не имеют взаимозависимостей.x
уже являетсяDataFrame
, так что вы можете просто добавить его в список, а затем объединить их в конце. Но если вы можете поместить весь файл в память для начала, так как вы собираетесь объединить в конце, не читайте его порциями. Это действительно для случаев, когда вы не можете поместить все это в память и вам нужно обрабатывать отдельные части по одной.