将for循环调整为列表理解

时间:2016-09-28 16:11:08

标签: pandas

我遍历数据库中的表和日期列表以收集数据。像这样:

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)

它看起来更好,图表显示它表现更好但是当我尝试调整自己的代码时,我似乎无法绕过它。

编辑 -

如果我制作一个查询列表似乎有效。有没有办法将循环和.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]

2 个答案:

答案 0 :(得分:3)

我不认为列表理解本身会给你带来显着的性能提升。我的意思是,与循环相比,它可能会给你带来轻微的性能提升,但我认为它与其他需要完成的事情相比并不重要,例如:查询数据库,初始化数据帧,结束。

通过使用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)

答案 1 :(得分:1)

我认为这应该有用

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;']