Python Pandas-使用to_sql以块的形式编写大型数据帧

Python Pandas-使用to_sql以块的形式编写大型数据帧,python,mysql,sql,pandas,sqlalchemy,Python,Mysql,Sql,Pandas,Sqlalchemy,我正在使用Pandas的to_sql函数来写入MySQL,这是由于大的帧大小(1M行,20列)而超时 是否有一种更正式的方法来对数据进行分块并以块的形式写入行?我已经编写了自己的代码,看起来很有效。不过我更喜欢正式的解决方案。谢谢 def write_to_db(engine, frame, table_name, chunk_size): start_index = 0 end_index = chunk_size if chunk_size < len(frame)

我正在使用Pandas的
to_sql
函数来写入MySQL,这是由于大的帧大小(1M行,20列)而超时

是否有一种更正式的方法来对数据进行分块并以块的形式写入行?我已经编写了自己的代码,看起来很有效。不过我更喜欢正式的解决方案。谢谢

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)
def write_to_db(引擎、帧、表名称、块大小):
开始索引=0
结束索引=块大小,如果块大小
提供了一些漂亮的惯用函数块来回答这个问题

在您的情况下,您可以这样使用此功能:

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)

唯一的缺点是它不支持在iloc函数中切片第二个索引。

更新:此功能已合并到pandas master中,并将于0.15(可能在9月底)发布,这要感谢@artemyk!看

因此,从0.15开始,您可以指定
chunksize
参数,例如,只需执行以下操作:

df.to_sql('table', engine, chunksize=20000)

fwiw,我必须做这件事。目前没有正式的解决方案,但我们肯定会接受一个补丁来实现这一点(关于
read\u sql
()的chunksize存在一个问题,您可以随时为此打开一个)。我创建了一个问题@乔里斯-如果你不介意的话,请在这里添加评论并支持我:)。为什么不将数据导出为csv文件(必须采用表格格式),然后使用load data infile命令?