Kri*_*pta 15 python mysql sql sqlalchemy pandas
我正在使用Pandas的to_sql
函数写入MySQL,由于帧大(1M行,20列)而导致超时.
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html
有没有更正式的方法来分块数据并在块中写行?我编写了自己的代码,这似乎有用.我更喜欢官方解决方案.谢谢!
def write_to_db(engine, frame, table_name, chunk_size):
start_index = 0
end_index = chunk_size if chunk_size < len(frame) else len(frame)
frame = frame.where(pd.notnull(frame), None)
if_exists_param = 'replace'
while start_index != end_index:
print "Writing rows %s through %s" % (start_index, end_index)
frame.iloc[start_index:end_index, :].to_sql(con=engine, name=table_name, if_exists=if_exists_param)
if_exists_param = 'append'
start_index = min(start_index + chunk_size, len(frame))
end_index = min(end_index + chunk_size, len(frame))
engine = sqlalchemy.create_engine('mysql://...') #database details omited
write_to_db(engine, frame, 'retail_pendingcustomers', 20000)
Run Code Online (Sandbox Code Playgroud)
jor*_*ris 18
更新:此功能已在pandas master中合并,并将在0.15(可能是9月底)发布,感谢@artemyk!请参阅https://github.com/pydata/pandas/pull/8062
所以从0.15开始,你可以指定chunksize
参数,例如:
df.to_sql('table', engine, chunksize=20000)
Run Code Online (Sandbox Code Playgroud)
小智 1
提供了漂亮的惯用函数块来回答这个问题
在你的情况下,你可以像这样使用这个函数:
def chunks(l, n):
""" Yield successive n-sized chunks from l.
"""
for i in xrange(0, len(l), n):
yield l.iloc[i:i+n]
def write_to_db(engine, frame, table_name, chunk_size):
for idx, chunk in enumerate(chunks(frame, chunk_size)):
if idx == 0:
if_exists_param = 'replace':
else:
if_exists_param = 'append'
chunk.to_sql(con=engine, name=table_name, if_exists=if_exists_param)
Run Code Online (Sandbox Code Playgroud)
唯一的缺点是它不支持在 iloc 函数中切片第二个索引。