I am using the following code to import database table into a DataFrame:
def import_db_table(chunk_size, offset):
dfs_ct = []
j = 0
start = dt.datetime.now()
df = pd.DataFrame()
while True:
sql_ct = "SELECT * FROM my_table limit %d offset %d" % (chunk_size, offset)
dfs_ct.append(psql.read_sql_query(sql_ct, connection))
offset += chunk_size
if len(dfs_ct[-1]) < chunk_size:
break
df = pd.concat(dfs_ct)
# Convert columns to datetime
columns = ['col1', 'col2', 'col3','col4', 'col5', 'col6',
'col7', 'col8', 'col9', 'col10', 'col11', 'col12',
'col13', 'col14', 'col15']
for column in columns:
df[column] = pd.to_datetime(df[column], errors='coerce')
# Remove the uninteresting columns
columns_remove = ['col42', 'col43', 'col67','col52', 'col39', 'col48','col49', 'col50', 'col60', 'col61', 'col62', 'col63', 'col64','col75', 'col80']
for c in df.columns:
if c not in columns_remove:
df = df.drop(c, axis=1)
j+=1
print('{} seconds: completed {} rows'.format((dt.datetime.now() - start).seconds, j*chunk_size))
return df
I am calling it with:
df = import_db_table(100000, 0)
This seems to be very slow - it starts with importing 100000 rows in 7 seconds but later after 1 million rows the number of seconds needed grows to 40-50 and more. Could this be improved somehow? I am using PostgreSQL, Python 3.5.
7 seconds: completed 100000 rows
17 seconds: completed 200000 rows
30 seconds: completed 300000 rows
47 seconds: completed 400000 rows
69 seconds: completed 500000 rows
92 seconds: completed 600000 rows
121 seconds: completed 700000 rows
153 seconds: completed 800000 rows
188 seconds: completed 900000 rows
228 seconds: completed 1000000 rows
271 seconds: completed 1100000 rows
318 seconds: completed 1200000 rows
368 seconds: completed 1300000 rows
422 seconds: completed 1400000 rows
480 seconds: completed 1500000 rows
540 seconds: completed 1600000 rows
605 seconds: completed 1700000 rows
674 seconds: completed 1800000 rows
746 seconds: completed 1900000 rows
dfs_ct
every iteration of the while loop? Otherwise it looks like you add all previously added entries as well as the next chunk. This would explain why it gets slower and slower... \$\endgroup\$df_chunk = psql.read_sql_query(sql_ct, connection); # check for abort condition; df = pd.concat(df, df_chunk)
inside the loop. Doing it outside the loop will be faster (but will have a list of all chunk data frames in memory, just like your current code). Doing it inside the loop has the added overhead of calling the function everytime but only ever has one chunk in memory (and the total dataframe). \$\endgroup\$