Pandas SQL chunksize

Это больше вопрос понимания, чем программирования. Я новичок в Pandas и SQL. Я использую Pandas для чтения данных из SQL с некоторым определенным chunksize. Когда я запускаю sql-запрос, например. import Pandas как pd

df = pd.read_sql_query('select name, birthdate from table1', chunksize = 1000)

То, что я не понимаю, - это когда я не даю chunksize, данные хранятся в памяти, и я могу видеть рост памяти, однако, когда я даю chunksize, использование памяти не так уж и велико.

У меня есть то, что этот df теперь содержит несколько массивов, к которым я могу получить доступ как

for df_array in df:
    print df.head(5)

То, что я не понимаю здесь, - это то, что весь результат инструкции SQL хранится в памяти, т.е. df - это объект, несущий несколько массивов, или если они похожи на указатели, указывающие на таблицу temp, созданную SQL-запросом.

Я был бы очень рад узнать, как этот процесс действительно работает.

Ответ 1

Рассмотрим два варианта и что происходит в обоих случаях:

  • chunksize - None (значение по умолчанию):
    • pandas передает запрос в базу данных
    • выполняет запрос
    • pandas проверяет и видит, что chunksize is None
    • pandas сообщает базе данных о том, что он хочет сразу получить все строки таблицы результатов
    • возвращает все строки таблицы результатов
    • pandas хранит таблицу результатов в памяти и переносит ее в фрейм данных
    • теперь вы можете использовать фрейм данных
  • chunksize in not None:
    • pandas передает запрос в базу данных
    • выполняет запрос
    • pandas проверяет и видит, что chunksize имеет некоторое значение
    • pandas создает итератор запроса (обычный цикл while, который прерывается, когда база данных говорит, что осталось больше данных) и повторяется каждый раз, когда вы хотите следующий фрагмент таблицы результатов
    • pandas сообщает базе данных о том, что он хочет получать строки chunksize База данных
    • возвращает следующие строки chunksize из таблицы результатов.
    • pandas хранит следующие строки chunksize в памяти и переносит их в фрейм данных
    • теперь вы можете использовать фрейм данных

Для получения дополнительной информации вы можете увидеть pandas\io\sql.py модуль, он хорошо документирован

Ответ 2

Если вы не указали chunksize, полный результат запроса сразу помещается в фреймворк.

Когда вы предоставляете chunksize, возвращаемое значение read_sql_query является итератором нескольких фреймов данных. Это означает, что вы можете выполнить итерацию следующим образом:

for df in result:
    print df

и на каждом шаге df - это dataframe (а не массив!), который содержит данные части запроса. Смотрите следующие документы: http://pandas.pydata.org/pandas-docs/stable/io.html#querying

Чтобы ответить на вопрос о памяти, вы должны знать, что для получения данных из базы данных есть два шага: execute и fetch.
Сначала выполняется запрос (result = con.execute()), а затем данные извлекаются из этого результирующего набора в виде списка кортежей (data = result.fetch()). При извлечении вы можете указать, сколько строк вы хотите извлечь. И это то, что pandas делает, когда вы предоставляете chunksize.
Но многие драйверы баз данных уже помещают все данные в память на этапе выполнения, а не только при извлечении данных. Поэтому в этом отношении это не имеет большого значения для памяти. Помимо факта, что копирование данных в DataFrame происходит только в разных шагах, итерации с помощью chunksize.