Недостаточно памяти: передача больших данных из Amazon Redshift в Pandas - PullRequest
0 голосов
/ 04 мая 2018

У меня есть большой блок данных (около 10 миллионов строк) в Amazon-Redishift, который я должен был получить во фрейме данных Pandas и сохранить данные в файле рассылки. Тем не менее, он показывает исключение «Недостаточно памяти» по понятным причинам из-за размера данных. Я пробовал много других вещей, таких как sqlalchemy, однако, не смог взломать проблему. Может кто-нибудь предложить лучший способ или код, чтобы пройти через это.

Мой текущий (простой) фрагмент кода выглядит следующим образом:

import psycopg2 

import pandas as pd

import numpy as np

cnxn = psycopg2.connect(dbname=<mydatabase>, host='my_redshift_Server_Name', port='5439', user=<username>, password=<pwd>)

sql = "Select * from mydatabase.mytable" 

df = pd.read_sql(sql, cnxn, columns=1)

pd.to_pickle(df, 'Base_Data.pkl')

print(df.head(50))

cnxn.close()

print(df.head(50))

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Если вы используете pickle для передачи данных куда-то еще, я бы повторил предложение из ответа AlexYes - просто используйте S3.

Но если вы хотите работать с данными локально, вы должны ограничиться алгоритмами, которые не требуют работы всех данных. В этом случае я бы предложил что-то вроде HDF5 или Паркет для хранения данных и Dask для обработки данных, поскольку не требуется, чтобы все данные находились в память - она ​​может работать порциями и параллельно. Вы можете перенести свои данные из Redshift, используя этот код:

from dask import dataframe as dd

d = dd.read_sql_table(my_table, my_db_url, index_col=my_table_index_col)
d.to_hdf('Base_Data.hd5', key='data')
0 голосов
/ 04 мая 2018

1) найдите количество строк в таблице и максимальный кусок таблицы, который вы можете извлечь, добавив order by [column] limit [number] offset 0 и разумно увеличив число номеров

2) добавить цикл, который будет производить sql с найденным вами пределом и увеличивать смещение, т. Е. Если вы сможете получить 10 тыс. Строк, ваши операторы будут:

... limit 10000 offset 0;
... limit 10000 offset 10000;
... limit 10000 offset 20000;

пока вы не достигнете числа строк таблицы

3) в том же цикле добавьте каждый новый полученный набор строк в ваш фрейм данных.

p.s. это будет работать, если вы не столкнетесь с какими-либо проблемами с памятью / диском на стороне клиента, что я не могу гарантировать, поскольку у вас есть такая проблема в кластере, который, вероятно, является аппаратным обеспечением более высокого класса. Чтобы избежать этой проблемы, вы просто пишете новый файл на каждой итерации вместо добавления.

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

...