试图找到将 SQL Query 转换为具有大量记录的 Pandas DataFrame 的最有效方法
Posted
技术标签:
【中文标题】试图找到将 SQL Query 转换为具有大量记录的 Pandas DataFrame 的最有效方法【英文标题】:Trying to find the most efficient way to convert SQL Query to Pandas DataFrame that has large number of records 【发布时间】:2018-10-15 11:45:25 【问题描述】:我正在尝试查询 MS-SQL 数据库视图并将结果转换为 Pandas DataFrame。
以下是我尝试的两种不同方法,在这两种情况下,查询并转换为具有 415076 条记录的 DataFrame 都需要约 439.98 秒(约 7 分钟)(这次是将其转换为 DataFrame,而不是用于数据检索)。这是我的应用业务逻辑对用户请求的数据输入/检索部分的典型案例。
注意:对于记录较少的查询(例如在 x1000 中),查询结果到 DataFrame 的转换性能在这两种情况下都很快。
query = """ SELECT *
FROM db_view_name
WHERE CONDITION_1 = %d AND
CONDITION_2 IN (%s) """ %(int(val), ','.join(map(str, my_values_list)))
con = pyodbc.connect(con_string)
Case 1:
cursor = con.cursor()
result = cursor.execute(query)
items = [dict(zip([key[0] for key in cursor.description], row)) for row in result]
df = pd.DataFrame(items)
Case 2:
df = pd.read_sql_query(query, con)
我的环境:我正在使用 Python 3.6 和 Pyramid Web 框架和 SQLAlchemy ORM。
如何减少处理这么多记录所需的时间?对此问题的任何帮助将不胜感激:)
【问题讨论】:
为了澄清,您能否确认不是数据检索而是转换为数据帧需要这么长时间? 我在描述中更新了,谢谢@Thornhale 尝试from_records
避免 items 构建:pd.DataFrame.from_records(result, columns=[key[0] for key in cursor.description])
@Parfait 我尝试使用 from_records 但仍然需要相同的时间来执行。
【参考方案1】:
仅供参考(我们已经讨论过)。
上面几行代码中比较慢的部分是 SQL 返回到 pandas 数据帧的转换。鉴于 Python 的默认行为,这一步不仅速度慢而且是单线程的。
为了避免这种行为,一种强制处理的方法是在单独的进程中发送 x 个子查询。
一旦我们得到子查询的结果,通过 pd.concat 组装单个数据帧实际上很快。
由于您正在研究并行化任务,请考虑以下“分布式计算”库:
黎明:http://dask.pydata.org/en/latest/ 分布:http://docs.enthought.com/distarray/ 雷:https://ray-project.github.io/2017/05/20/announcing-ray.html如果您愿意将其他库添加到依赖项列表中,所有这些都使您能够以更高的自动化程度并行化任务。
另一种方法是在 Python 核心本身中使用多进程功能。
【讨论】:
非常感谢您的想法@Thornhale以上是关于试图找到将 SQL Query 转换为具有大量记录的 Pandas DataFrame 的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章