【问题标题】:Why does a pandas dataframe consumes much more RAM than the size of the original text file?为什么熊猫数据框消耗的 RAM 比原始文本文件的大小要多得多?
【发布时间】:2019-11-01 19:54:23
【问题描述】:

我正在尝试使用 pandas pd.read_csv("file.txt",sep="\t") 将一个大的 tab/txt(大小 = 3 gb)文件导入 Python。我加载的文件是一个“.tab”文件,我将扩展名更改为“.txt”以使用read_csv() 导入它。这是一个包含 305 列和 +/- 1 000 000 行的文件。

当我执行代码时,一段时间后 Python 返回一个 MemoryError。我搜索了一些信息,这基本上意味着没有足够的 RAM 可用。当我在 read_csv() 中指定 nrows = 20 时,它工作正常。

我使用的计算机有 46gb 的 RAM,其中大约 20gb 可用于 Python。

我的问题:如何使用 pandas read_csv() 将 3gb 的文件需要超过 20gb 的 RAM 导入 Python?我做错什么了吗?

编辑:在执行df.dtypes 时,类型是object、float64 和int64 的混合类型

更新:我使用以下代码来解决问题并执行我的计算:

summed_cols=pd.DataFrame(columns=["sample","read sum"])
while x<352:
    x=x+1
    sample_col=pd.read_csv("file.txt",sep="\t",usecols=[x])
    summed_cols=summed_cols.append(pd.DataFrame({"sample":[sample_col.columns[0]],"read sum":sum(sample_col[sample_col.columns[0]])}))
    del sample_col

它现在选择一列,执行计算,将结果存储在数据框中,删除当前列,然后移动到下一列

【问题讨论】:

  • 感谢您的链接!搜索信息时没有弹出这个!
  • 一种可能的解决方案是分块读取文件。见this other question。
  • @AlCorreia 我也考虑过该解决方案,但由于我必须计算整个列的总和,因此加载行块似乎不是一个好的解决方案。遍历列(请参阅我的更新)效果很好。

标签: python pandas


【解决方案1】:

Pandas 正在切割文件,并单独存储数据。我不知道数据类型,所以我会假设最坏的情况:字符串。

在 Python(在我的机器上)中,一个空字符串需要 49 个字节,如果是 ASCII,则每个字符需要一个额外的字节(如果是 Unicode,则需要 74 个字节,每个字符需要额外的 2 个字节)。对于一行 305 个空字段,这大约是 15Kb。 100 万个这样的行大约需要 22Gb 的内存,而在 CSV 文件中大约需要 437 Mb。

Pandas/numpy 擅长处理数字,因为它们可以非常紧凑地表示数字序列(就像 C 程序一样)。一旦你离开与 C 兼容的数据类型,它就会像 Python 一样使用内存,这……不是很节俭。

【讨论】:

  • 感谢您的回复!当我执行 type(df[df.columns[1]][5]] (1 和 5 是任意数字)python 返回 &lt;class 'numpy.float64''&gt; 。这些不是字符串,所以内存峰值仍然有意义吗?
  • 这只是证明了一列。检查df.dtypes。如果其中任何一个是object,则该列将存储为 Python 对象。另一种可能性是……你确实需要比你拥有的更多的内存。文件有多少行?
  • 我为 df.dtypes 编辑了我的原始帖子。当它被报道为object时,后果是什么?
  • object dtype 表示它存储为 Python 对象。 sys.getsizeof(1) 会告诉你(至少在我的电脑上)Python 表示一个具有 28 字节内存的整数。 sys.getsizeof("") 将确认我之前所说的关于 Python 字符串的内容。但是,np.float64 和 np.int64 各自只使用 8 个字节(=64 位)。
  • 对我来说,Python 返回以下内容:sys.getsizeof("object") = 31 - sys.getsizeof("float64") = 32 - sys.getsizeof("int64") = 30。这些数字远高于您的值?这怎么可能?
猜你喜欢
  • 2020-04-12
  • 1970-01-01
  • 2018-02-08
  • 2023-03-30
  • 2012-10-26
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多