将pandas数据帧转换为内存中类似文件的对象?

时间:2016-07-05 12:56:36

标签: pandas psycopg2

我每天在Postgres数据库中加载大约2到250万条记录。

然后我用pd.read_sql读取这些数据,将其转换为数据帧,然后进行一些列操作和一些小的合并。我将此修改后的数据另存为一个单独的表供其他人使用。

当我做pd.to_sql时,它需要永远。如果我保存一个csv文件并在Postgres中使用COPY FROM,整个过程只需要几分钟,但服务器在一台单独的机器上,在那里传输文件很痛苦。

使用psycopg2,看起来我可以使用copy_expert从批量复制中受益,但仍然使用python。我希望,如果可能的话,避免编写实际的csv文件。我可以在内存中使用pandas数据帧吗?

以下是我的pandas代码的示例。我想添加copy_expert或其他东西,以便尽可能快地保存这些数据。

    for date in required_date_range:
        df = pd.read_sql(sql=query, con=pg_engine, params={'x' : date})
        ...
        do stuff to the columns
        ...
        df.to_sql('table_name', pg_engine, index=False, if_exists='append',  dtype=final_table_dtypes)

有人可以通过示例代码帮助我吗?我更喜欢使用熊猫,在内存中做它会很好。如果没有,我只会编写一个csv临时文件并以这种方式执行。

编辑 - 这是我的最终代码。每个日期(数百万行)只需要几百秒而不是几个小时。

to_sql =“”“COPY%s FROM STDIN WITH CSV HEADER”“”

def process_file(conn, table_name, file_object):
    fake_conn = cms_dtypes.pg_engine.raw_connection()
    fake_cur = fake_conn.cursor()
    fake_cur.copy_expert(sql=to_sql % table_name, file=file_object)
    fake_conn.commit()
    fake_cur.close()


#after doing stuff to the dataframe
    s_buf = io.StringIO()
    df.to_csv(s_buf) 
    process_file(cms_dtypes.pg_engine, 'fact_cms_employee', s_buf)

2 个答案:

答案 0 :(得分:18)

Python模块iodocs)具有类似文件对象的必要工具。

import io

# text buffer
s_buf = io.StringIO()

# saving a data frame to a buffer (same as with a regular file):
df.to_csv(s_buf)

修改 (我忘了)为了之后从缓冲区读取,它的位置应该设置为开头:

s_buf.seek(0)

我不熟悉psycopg2,但根据docs,可以使用copy_expertcopy_from,例如:

cur.copy_from(s_buf, table)

(对于Python 2,请参阅StringIO。)

答案 1 :(得分:4)

我在从ptrj实现解决方案时遇到了问题。

我认为这个问题源于大熊猫将缓冲区的位置设置到最后。

见如下:

  <logger message="print substring of value: #[json:color] level="INFO" doc:name="Logger"/>

请注意,pos是12.我必须将pos设置为0,以便后续的copy_from命令工作

<logger message="print substring of value: #[json:color].substring(0,1) level="INFO" doc:name="Logger"/>