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

2024-05-15 18:00:08 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

当我做警察的时候,要花很长时间。如果我保存一个csv文件并使用Postgres中的COPY FROM,整个过程只需要几分钟,但是服务器在一台单独的机器上,在那里传输文件很痛苦。

使用psycopg2,看起来我可以使用copy_expert从大容量复制中获益,但仍然使用python。如果可能的话,我想避免写一个真正的csv文件。我能用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临时文件,并这样做。

编辑-这是我的最后一个工作代码。每次约会只需要几百秒(数百万行),而不是几个小时。

“将%s从带有CSV头的STDIN复制到”

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)

Tags: 文件csvto数据dfsqldatetable
2条回答

我在执行ptrj的解决方案时遇到问题。

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

见下表:

from StringIO import StringIO
df = pd.DataFrame({"name":['foo','bar'],"id":[1,2]})
s_buf = StringIO()
df.to_csv(s_buf)
s_buf.__dict__

# Output
# {'softspace': 0, 'buflist': ['foo,1\n', 'bar,2\n'], 'pos': 12, 'len': 12, 'closed': False, 'buf': ''}

注意位置是12。我必须将pos设置为0以便随后从命令复制到工作

s_buf.pos = 0
cur = conn.cursor()
cur.copy_from(s_buf, tablename, sep=',')
conn.commit()

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。)

相关问题 更多 >