一尘不染

如何在不耗尽内存的情况下通过sql查询创建大熊猫数据框?

python

我无法从MS SQL Server数据库查询超过500万条记录的表。我想选择所有的记录,但我的代码似乎选择以多数据时到内存失败。

这有效:

import pandas.io.sql as psql
sql = "SELECT TOP 1000000 * FROM MyTable" 
data = psql.read_frame(sql, cnxn)

…但这不起作用:

sql = "SELECT TOP 2000000 * FROM MyTable" 
data = psql.read_frame(sql, cnxn)

它返回此错误:

File "inference.pyx", line 931, in pandas.lib.to_object_array_tuples
(pandas\lib.c:42733) Memory Error

我在[这里](http://codingdict.com/questions/176669已经读到,dataframe从csv文件创建时存在类似的问题,解决方法是使用“ iterator”和“
chunksize”参数,如下所示:

read_csv('exp4326.csv', iterator=True, chunksize=1000)

从SQL数据库查询是否有类似的解决方案?如果没有,首选的解决方法是什么?我是否应该使用其他方法来分块读取记录?我在这里阅读了一些有关在熊猫中使用大型数据集的讨论,但是执行SELECT
*查询似乎需要做很多工作。当然,有一种更简单的方法。


阅读 182

收藏
2021-01-20

共1个答案

一尘不染

更新:请确保检查以下答案,因为Pandas现在具有对分块加载的内置支持。

您可以简单地尝试逐块读取输入表,然后从各个部分组装完整的数据框,如下所示:

import pandas as pd
import pandas.io.sql as psql
chunk_size = 10000
offset = 0
dfs = []
while True:
  sql = "SELECT * FROM MyTable limit %d offset %d order by ID" % (chunk_size,offset) 
  dfs.append(psql.read_frame(sql, cnxn))
  offset += chunk_size
  if len(dfs[-1]) < chunk_size:
    break
full_df = pd.concat(dfs)

整个数据帧也可能太大而无法容纳在内存中,在这种情况下,除了限制选择的行数或列数之外,您别无选择。

2021-01-20