Pandas: how to work with really big data?
我的数据样本非常大(120万个文档),我只需要在一个"pandas数据帧"上创建和分析数据。 现在我的代码看起来像这样:
1 2 3 4 5 | conn = psycopg2.connect("dbname=monty user=postgres host=localhost password=postgres") cur = conn.cursor('aggre') cur.execute("SELECT * FROM binance.zrxeth_ob_indicators;") row = cur.fetchall() df = pd.DataFrame(row,columns = ['timestamp', 'topAsk', 'topBid', 'CPA', 'midprice', 'CPB', 'spread', 'CPA%', 'CPB%']) |
但是,在变量df中上传所有东西需要很长时间吗? 我到目前为止尝试的是这样做:
1 2 3 | for row in cur: dfsub = pd.DataFrame(row,columns=['timestamp', 'topAsk', 'topBid', 'CPA', 'midprice', 'CPB', 'spread', 'CPA%', 'CPB%']) df = df.concat([df,dfsub]) |
但它给我以下错误:DataFrame构造函数未正确调用!
任何的想法? 谢谢!
Pandas有一个很好的内置
即只做:
1 | df = pd.read_sql("SELECT * FROM binance.zrxeth_ob_indicators", conn) |
它应该工作......
在它自己的120万行上并不多,鉴于你的列数/名称它可能<300MB的RAM(每个值30个字节* 9列* 1.2e6行)并且在最近的计算机上应该花费<10秒
你可以做这样的事情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class Postgres: def __init__(self, host, database, user=None, password='', schema='public'): self.user = user or getpass.getuser() self.database = database self.host = host self.engine = self.create_engine(self.host, self.database, self.user, password) self.schema = schema @staticmethod def create_engine(host, database, user, password): return psycopg2.connect("postgresql://{user}:{password}@{host}/{database}".format( host=host, database=database, user=user, password=password )) def execute(self, query: object) -> object: """ :param query: :return: pd.Dataframe() """ result_df = pd.read_sql(query, self.engine) self.engine.commit() return result_df |
有了这个,你可以使用pardas的postgres结果创建优化的DataFrame。
但是根据您的数据集推理,将所有数据读入内存需要一些时间
我认为,由于你的文档集很大,无论你如何处理它都需要很长时间才能将它加载到内存中。我建议,如果你不需要一次将整个数据集保存在内存中,你可以使用pandas内置的加载块方法。这允许您按顺序加载和处理为此用例设计的数据块。
例如,请参阅此问题
如何阅读带有pandas的6 GB csv文件