Ответ 1
Устаревшая опция low_memory
Опция low_memory
не рекомендуется должным образом, но она должна быть, так как на самом деле она не делает ничего по-другому [ источник ]
Причина, по которой вы получаете это предупреждение low_memory
заключается в том, что угадывание dtypes для каждого столбца требует очень много памяти. Pandas пытается определить тип dtype, анализируя данные в каждом столбце.
D-тип догадки (очень плохо)
Pandas может определить, какой тип d должен иметь столбец, только после того, как будет прочитан весь файл. Это означает, что на самом деле ничего не может быть проанализировано до того, как будет прочитан весь файл, если вы не рискуете изменить dtype этого столбца при чтении последнего значения.
Рассмотрим пример одного файла, в котором есть столбец с именем user_id. Он содержит 10 миллионов строк, где user_id - это всегда числа. Поскольку pandas не может знать, что это только числа, он, вероятно, будет сохранять его как исходные строки, пока не прочитает весь файл.
Указание dtypes (всегда должно быть сделано)
добавление
dtype={'user_id': int}
pd.read_csv()
заставит панд узнать, когда он начнет читать файл, что это только целые числа.
Также стоит отметить, что если в последней строке файла будет записан "foobar"
в столбце user_id
, загрузка завершится user_id
, если указан вышеупомянутый dtype.
Пример сломанных данных, которые ломаются, когда определены dtypes
import pandas as pd
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
csvdata = """user_id,username
1,Alice
3,Bob
foobar,Caesar"""
sio = StringIO(csvdata)
pd.read_csv(sio, dtype={"user_id": int, "username": object})
ValueError: invalid literal for long() with base 10: 'foobar'
Типы dtypes, как правило, не совсем понятны, подробнее о них можно прочитать здесь: http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html.
Какие существуют типы?
Это ntypty dtypes, которые также принимаются в пандах
[numpy.generic,
[[numpy.number,
[[numpy.integer,
[[numpy.signedinteger,
[numpy.int8,
numpy.int16,
numpy.int32,
numpy.int64,
numpy.int64,
numpy.timedelta64]],
[numpy.unsignedinteger,
[numpy.uint8,
numpy.uint16,
numpy.uint32,
numpy.uint64,
numpy.uint64]]]],
[numpy.inexact,
[[numpy.floating,
[numpy.float16, numpy.float32, numpy.float64, numpy.float128]],
[numpy.complexfloating,
[numpy.complex64, numpy.complex128, numpy.complex256]]]]]],
[numpy.flexible,
[[numpy.character, [numpy.bytes_, numpy.str_]],
[numpy.void, [numpy.record]]]],
numpy.bool_,
numpy.datetime64,
numpy.object_]]
Pandas также добавляет два dtypes: categorical
и datetime64[ns, tz]
, которые недоступны в numpy
Gotchas, предостережения, заметки
Установка dtype=object
заставит замолчать вышеупомянутое предупреждение, но не сделает его более эффективным с точки зрения памяти, а эффективнее всего процесса.
Установка dtype=unicode
ничего не изменит, поскольку, к сожалению, unicode
представляется как object
.
Использование конвертеров
@sparrow правильно указывает на использование конвертеров, чтобы избежать взрыва панд при обнаружении 'foobar'
в столбце, указанном как int
. Я хотел бы добавить, что преобразователи действительно тяжелые и неэффективные для использования в пандах и должны использоваться в качестве крайней меры. Это потому, что процесс read_csv является отдельным процессом.
CSV файлы могут обрабатываться построчно и, следовательно, могут обрабатываться несколькими конвертерами параллельно более эффективно, просто разрезая файл на сегменты и выполняя несколько процессов, чего не поддерживает pandas. Но это другая история.