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
.