0

长话短说,我一直在努力解决内存问题(以及执行时间)dask/pandas编写大型数据框to_sql,或者to_csv是否有人可以指出我正确的方向(下面有更多详细信息)?

我将两个大的 .csv 文件附加在一起以形成一个更大的 .csv 文件(27M 行 x 52 列),dask以便节省内存而不是使用pandas,因为我的内存不足或接近它。

从那里,我只是试图写入 a .csv,但我再次耗尽内存,试图用于.compute()从 dask 数据帧转换为 pandas 数据帧并写入文件。我想把这个问题集中在如何简单地将这个东西放入 .csv 而不会耗尽内存。从那里,我计划使用 SQL Server 的导入向导将文件导入数据库中的新表。请参阅下面的代码,了解我如何读取和concat'ing 作为 dask 数据帧,转换为 pandas 数据帧,然后在内存不足之前尝试写入 .csv:

df1 = dd.read_csv('C:/Users/david.erickson/file1.csv', dtype={'Phone #': str, 'Called #': str})
df2 = dd.read_csv('C:/Users/david.erickson/file2.csv', dtype={'Phone #': str, 'Called #': str})
df_combined = dd.concat([df1,df2], axis=0).drop_duplicates()
df_combined = df_combined.compute()
df_combined.to_csv('C:/Users/david.erickson/file_combined.csv', index=False)

在观看 python 接近 38 GB 的已提交物理内存后,我在第四行或第五行遇到内存错误:

MemoryError: Unable to allocate 210. MiB for an array with shape (27571126,) and data type int64

在任何人提到它之前,我也孜孜不倦地尝试过to_sql,但没有成功,因为最终目标是将这些数据放入 SQL Sever 数据库中。它一直持续下去,我遇到了sqlalchemy's 的内存错误to_sql。更好的是,我希望我可以直接写入 SQL Server,这就是我尝试过的:

engine = sa.create_engine(cnxn_string, fast_executemany=True)
connection = engine.connect()
df.to_sql('New_Table', con=engine, if_exists='replace', index=False) 

我也试过:df6.to_sql('New_Table', con=engine, if_exists='replace', index=False, chunksize=40, method='multi')#有2098个参数的限制,这就是为什么chunksize=40(40*52列=2080,所以小于限制。反正这比只传递fast_executemany=True给要慢create_engine)

不幸的是,上面提到的尝试以及sqlalchemy我研究的其他一些 python 方法.to_sql只是内存不足,或者操作需要很长时间(一夜之间),我不得不杀死它。

在 52 列和 2750 万行中,我猜每个单元格的平均字符串大小约为 20 个字符(至少对于文本列而言)。我必须做一些不同的事情才能将这些数据导入 SQL Server 数据库,但我真的很挣扎,我在这个项目之前to_sqlto_csv之前从未遇到过更多数据的问题。

处理器

记忆

4

1 回答 1

1

假设 CSV 有类似主键的东西,拆分数据集。如果您有 52 列,请将其拆分为 4 帧和 14 列(每列 4x 13,并复制主键列以便匹配它们),然后将较小的数据集传递给 SQL。

或者制作一个主键列表,只插入前 N 个,提交事务,然后开始下一批。

此外,MS SQL 有一个用于 .csv 的导入功能,由于它批量插入,因此效率相当高。为什么使用python作为两者之间的层?

于 2020-06-12T08:18:11.903 回答