酸洗熊猫数据帧将文件大小乘以5

时间:2015-05-15 07:32:20

标签: python csv pandas pickle

我正在阅读带有pandas.read_csv的800 Mb CSV文件,然后使用原始Python pickle.dump(datfarame)进行保存。结果是4 Gb pkl文件,因此CSV大小乘以5.

我希望pickle压缩数据而不是扩展它。另外,因为我可以在CSV文件上进行gzip压缩,将其压缩为200 Mb,将其除以4。

我愿意加快程序的加载时间,并认为酸洗会有所帮助,但考虑到磁盘访问是主要的瓶颈我理解我宁愿压缩文件然后使用来自{的压缩选项{1}}加快加载时间。

这是对的吗?

酸洗pandas数据框扩展数据大小是否正常?

你如何加快加载时间?

您使用pandas加载的数据大小限制是什么?

4 个答案:

答案 0 :(得分:2)

不确定为什么你认为酸洗压缩数据大小,pickling会创建python对象的字符串版本,以便它可以作为python对象加载回来:

In [388]:

import sys
import os
df = pd.DataFrame({'a':np.arange(5)})
df.to_pickle(r'c:\data\df.pkl')
print(sys.getsizeof(df))
statinfo = os.stat(r'c:\data\df.pkl')
print(statinfo.st_size)
with open(r'c:\data\df.pkl', 'rb') as f:
    print(f.read())
56
700
b'\x80\x04\x95\xb1\x02\x00\x00\x00\x00\x00\x00\x8c\x11pandas.core.frame\x94\x8c\tDataFrame\x94\x93\x94)}\x94\x92\x94\x8c\x15pandas.core.internals\x94\x8c\x0cBlockManager\x94\x93\x94)}\x94\x92\x94(]\x94(\x8c\x11pandas.core.index\x94\x8c\n_new_Index\x94\x93\x94h\x0b\x8c\x05Index\x94\x93\x94}\x94(\x8c\x04data\x94\x8c\x15numpy.core.multiarray\x94\x8c\x0c_reconstruct\x94\x93\x94\x8c\x05numpy\x94\x8c\x07ndarray\x94\x93\x94K\x00\x85\x94C\x01b\x94\x87\x94R\x94(K\x01K\x01\x85\x94\x8c\x05numpy\x94\x8c\x05dtype\x94\x93\x94\x8c\x02O8\x94K\x00K\x01\x87\x94R\x94(K\x03\x8c\x01|\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK?t\x94b\x89]\x94\x8c\x01a\x94at\x94b\x8c\x04name\x94Nu\x86\x94R\x94h\rh\x0b\x8c\nInt64Index\x94\x93\x94}\x94(h\x11h\x14h\x17K\x00\x85\x94h\x19\x87\x94R\x94(K\x01K\x05\x85\x94h\x1f\x8c\x02i8\x94K\x00K\x01\x87\x94R\x94(K\x03\x8c\x01<\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94b\x89C(\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x94t\x94bh(Nu\x86\x94R\x94e]\x94h\x14h\x17K\x00\x85\x94h\x19\x87\x94R\x94(K\x01K\x01K\x05\x86\x94h\x1f\x8c\x02i4\x94K\x00K\x01\x87\x94R\x94(K\x03h5NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94b\x89C\x14\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x94t\x94ba]\x94h\rh\x0f}\x94(h\x11h\x14h\x17K\x00\x85\x94h\x19\x87\x94R\x94(K\x01K\x01\x85\x94h"\x89]\x94h&at\x94bh(Nu\x86\x94R\x94a}\x94\x8c\x060.14.1\x94}\x94(\x8c\x06blocks\x94]\x94}\x94(\x8c\x06values\x94h>\x8c\x08mgr_locs\x94\x8c\x08builtins\x94\x8c\x05slice\x94\x93\x94K\x00K\x01K\x01\x87\x94R\x94ua\x8c\x04axes\x94h\nust\x94bb.'

方法to_csv支持压缩为kwarg'gzip''bz2'

In [390]:

df.to_csv(r'c:\data\df.zip', compression='bz2')
statinfo = os.stat(r'c:\data\df.zip')
print(statinfo.st_size)
29

答案 1 :(得分:2)

将CSV文件存储在某种数据库并对其执行操作可能符合您的最佳利益,而不是像Kathirmani建议的那样将CSV文件加载到RAM中。您将看到加载时间的加速,这是因为您每次加载脚本时都没有填满800 Mb的RAM。

文件压缩和加载时间是您似乎想要完成的两个相互矛盾的元素。压缩CSV文件并加载 more 时间;您现在已经添加了必须解压缩文件的额外步骤,但这并没有解决您的问题。

考虑将数据发送到sqlite3数据库的前提步骤,如下所述:Importing a CSV file into a sqlite3 database table using Python

您现在很高兴能够查询数据的子集并快速将其加载到pandas.DataFrame以供进一步使用,如下所示:

from pandas.io import sql
import sqlite3

conn = sqlite3.connect('your/database/path')
query = "SELECT * FROM foo WHERE bar = 'FOOBAR';"

results_df = sql.read_frame(query, con=conn)
...

相反,您可以使用pandas.DataFrame.to_sql()保存这些内容供以后使用。

答案 2 :(得分:0)

不要将800MB文件加载到内存中。这会增加你的加载时间。泡菜对象也需要更多时间来加载。而是将csv文件存储为sqlite3(随python一起提供)表。然后根据您的需要每次查询表格。

答案 3 :(得分:0)

你也可以使用熊猫的泡菜方法来压缩你的数据。

保存数据框:

df.to_pickle(filename)

加载它:

df = pd.read_pickle(filename)