循环遍历数据库中的表和日期列表以收集数据。像这样:
df_list = []
for table in table_list:
for date in required_date_range:
query = 'SELECT * FROM {} WHERE row_date = {};'.format(table, date)
df = pd.read_sql_query(sql=query, con=engine)
df_list.append(df)
result = pd.concat(df_list)
有没有办法把这样的循环放入列表推导式中?这值得吗?
我从https://tomaugspurger.github.io/modern-4-performance.html
找到了一些示例代码files = glob.glob('weather/*.csv')
weather_dfs = [pd.read_csv(fp, names=columns) for fp in files]
weather = pd.concat(weather_dfs)
它看起来更好,图表显示它的性能更好,但当我试图调整自己的代码时,我似乎就是无法理解它。
编辑-
如果我制作查询列表,似乎可以工作。有没有办法让初始的for循环和。format也变成列表推导式?
for table in table_list:
for date in required_date_range:
queries = ['SELECT * FROM {} WHERE row_date = {};'.format(table, date)]
dfs = [pd.read_sql_query(query, con=pg_engine) for query in queries]
我不认为列表理解本身会给你带来显著的性能提升。我的意思是,与循环相比,它可能会给你带来轻微的性能提升,但我认为相对于其他需要完成的事情来说,它并不重要,例如查询数据库,初始化数据帧,连接。
通过使用SQL IN
操作符来消除内部循环可能会给您带来性能提升:
SELECT * FROM table_name WHERE row_date IN (date1, date2, date3,...);
那么,这会把你的循环变成这样:
df_list = []
for table in table_list:
query = 'SELECT * FROM {} WHERE row_date IN ({});'.format(table, ','.join(date_range))
df = pd.read_sql_query(sql=query, con=engine)
df_list.append(df)
从这里可以很直接地将它转换为一个推导式:
query = 'SELECT * FROM {} WHERE row_date IN ({});'
dfs = (pd.read_sql_query(sql=query.format(table, ','.join(date_range)), con=engine) for table in table_list)
df = pd.concat(dfs)
如果每个表中的列相同且顺序相同,您甚至可以通过使用UNION ALL
沿着以下行构建单个查询来消除表循环:
SELECT * FROM table1 WHERE row_date IN (date1, date2, date3,...)
UNION ALL
SELECT * FROM table2 WHERE row_date IN (date1, date2, date3,...)
UNION ALL
...
然后只做一个read_sql_query
调用:
df = pd.read_sql_query(sql=union_all_query, con=engine)
我想这应该能行
def q(table, date):
query = 'SELECT * FROM {} WHERE row_date = {};'.format
return pd.read_sql_query(sql=query(table, date), con=engine)
df_list = [q(table, date) for table in table_list for date in required_date_range]
Dmonstration
注意:我切换到只返回查询,因为这是一个演示,我没有你的数据库连接。
table_list = ['table1', 'table2']
required_date_range = ['date1', 'date2']
def q(table, date):
query = 'SELECT * FROM {} WHERE row_date = {};'.format
return query(table, date)
df_list = [q(table, date) for table in table_list for date in required_date_range]
df_list
['SELECT * FROM table1 WHERE row_date = date1;',
'SELECT * FROM table1 WHERE row_date = date2;',
'SELECT * FROM table2 WHERE row_date = date1;',
'SELECT * FROM table2 WHERE row_date = date2;']