How to create a large pandas dataframe from an sql query without running out of memory?
我无法从我的MS SQL Server数据库查询一个超过500万条记录的表。我想能够选择所有的记录,但我的代码似乎失败时,选择大量的数据进入内存。
这工作:
1 2 3 | import pandas.io.sql as psql sql ="SELECT TOP 1000000 * FROM MyTable" data = psql.read_frame(sql, cnxn) |
…但这不起作用:
1 2 | sql ="SELECT TOP 2000000 * FROM MyTable" data = psql.read_frame(sql, cnxn) |
它返回此错误:
1 2 | File"inference.pyx", line 931, in pandas.lib.to_object_array_tuples (pandas\lib.c:42733) Memory Error |
我在这里读到,从csv文件创建数据帧时存在类似的问题,解决方法是使用"迭代器"和"chunksize"参数,如下所示:
1 | read_csv('exp4326.csv', iterator=True, chunksize=1000) |
对于从SQL数据库查询,是否有类似的解决方案?如果没有,你最喜欢的工作是什么?我需要用其他方法成批地读取记录吗?我在这里读了一些关于在熊猫中使用大型数据集的讨论,但是执行select*查询似乎需要很多工作。当然有一个更简单的方法。
如注释所述,从pandas 0.15开始,在
1 2 3 | sql ="SELECT * FROM My_Table" for chunk in pd.read_sql_query(sql , engine, chunksize=5): print(chunk) |
参考:http://pandas.pydata.org/pandas docs/version/0.15.2/io.html查询
更新:请务必查看下面的答案,因为熊猫现在已经内置了对分块加载的支持。
您只需尝试分块读取输入表,然后从各个部分组装完整的数据帧,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
也可能是整个数据帧太大,内存无法容纳,在这种情况下,除了限制要选择的行或列的数量之外,您没有其他选择。