Подтвердить что ты не робот

Pandas read_csv параметры low_memory и dtype

При вызове

df = pd.read_csv('somefile.csv')

Я получаю:

/Users/josh/anaconda/envs/py27/lib/python2.7/site-packages/pandas/io/parsers.py:1130: DtypeWarning: Столбцы (4,5,7,16) имеют смешанные типы. Укажите dtype вариант при импорте или установить low_memory = False.

Почему опция dtype связана с low_memory, и почему она помогла бы с этой проблемой?

4b9b3361

Ответ 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

Панда dtype ссылка

Gotchas, предостережения, заметки

Установка dtype=object заставит замолчать вышеупомянутое предупреждение, но не сделает его более эффективным с точки зрения памяти, а эффективнее всего процесса.

Установка dtype=unicode ничего не изменит, поскольку, к сожалению, unicode представляется как object.

Использование конвертеров

@sparrow правильно указывает на использование конвертеров, чтобы избежать взрыва панд при обнаружении 'foobar' в столбце, указанном как int. Я хотел бы добавить, что преобразователи действительно тяжелые и неэффективные для использования в пандах и должны использоваться в качестве крайней меры. Это потому, что процесс read_csv является отдельным процессом.

CSV файлы могут обрабатываться построчно и, следовательно, могут обрабатываться несколькими конвертерами параллельно более эффективно, просто разрезая файл на сегменты и выполняя несколько процессов, чего не поддерживает pandas. Но это другая история.

Ответ 2

Try:

dashboard_df = pd.read_csv(p_file, sep=',', error_bad_lines=False, index_col=False, dtype='unicode')

Согласно документации pandas:

dtype: имя типа или тип столбца → тип

Что касается low_memory, то True по умолчанию и еще не задокументирован. Я не думаю, что это имеет значение. Сообщение об ошибке является общим, поэтому вам все равно не нужно возиться с low_memory. Надеюсь, что это поможет и сообщит мне, если у вас есть дополнительные проблемы.

Ответ 3

df = pd.read_csv('somefile.csv', low_memory=False)

Это должно решить проблему. Я получил точно такую ​​же ошибку при чтении 1.8M строк из CSV.

Ответ 4

Как упоминалось ранее firelynx, если dtype явно указано, и есть смешанные данные, которые несовместимы с этим dtype, тогда загрузка приведет к сбою. В качестве обходного пути я использовал такой конвертер, чтобы изменить значения с несовместимым типом данных, чтобы данные все равно могли быть загружены.

def conv(val):
    if not val:
        return 0    
    try:
        return np.float64(val)
    except:        
        return np.float64(0)

df = pd.read_csv(csv_file,converters={'COL_A':conv,'COL_B':conv})

Ответ 5

У меня была похожая проблема с файлом ~ 400 МБ. Установка low_memory=False сделала свое дело для меня. Сначала сделайте простые вещи, я бы проверил, что ваш фрейм данных не превышает системную память, перезагрузите компьютер, очистите ОЗУ, прежде чем продолжить. Если вы все еще сталкиваетесь с ошибками, стоит убедиться, что ваш файл .csv исправен, взгляните в Excel и убедитесь в отсутствии явных повреждений. Сломанные исходные данные могут нанести ущерб...

Ответ 6

У меня это работало с low_memory = False при импорте DataFrame. Вот и все изменения, которые спомогли мне:

df = pd.read_csv('export4_16.csv',low_memory=False)