如何估算Pandas的DataFrame需要多少内存?

时间:2013-08-06 20:18:56

标签: python pandas

我一直想知道......如果我正在读一个400MB的csv文件到pandas数据帧(使用read_csv或read_table),有没有办法猜测这需要多少内存?只是想更好地感受数据帧和内存......

7 个答案:

答案 0 :(得分:57)

df.memory_usage()将返回每列占用的数量:

>>> df.memory_usage()

Row_ID            20906600
Household_ID      20906600
Vehicle           20906600
Calendar_Year     20906600
Model_Year        20906600
...

要包含索引,请传递index=True

所以要获得整体内存消耗:

>>> df.memory_usage(index=True).sum()
731731000

另外,传递memory_usage =' deep'将启用更准确的内存使用情况报告,以便充分利用所包含的对象。

这是因为如果deep = False(默认情况),内存使用量不包括不是数组成分的元素占用的内存。

答案 1 :(得分:40)

以下是不同方法的比较 - sys.getsizeof(df)最简单。

对于此示例,df是一个包含814行,11列(2个整数,9个对象)的数据帧 - 从427kb shapefile中读取

sys.getsizeof(DF)

>>> import sys
>>> sys.getsizeof(df)
(gives results in bytes)
462456

df.memory_usage()

>>> df.memory_usage()
...
(lists each column at 8 bytes/row)

>>> df.memory_usage().sum()
71712
(roughly rows * cols * 8 bytes)

>>> df.memory_usage(deep=True)
(lists each column's full memory usage)

>>> df.memory_usage(deep=True).sum()
(gives results in bytes)
462432

df.info()

将数据帧信息打印到stdout。从技术上讲,这些是kibibytes(KiB),而不是千字节 - 正如文档字符串所说,“内存使用以人类可读的单位显示(基数为2的表示)。”因此,获取字节将乘以1024,例如451.6 KiB = 462,438字节。

>>> df.info()
...
memory usage: 70.0+ KB

>>> df.info(memory_usage='deep')
...
memory usage: 451.6 KB

答案 2 :(得分:28)

你必须反过来做。

In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')

In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug  6 16:55 test.csv

技术上内存就是这个(包括索引)

In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160

因此内存为168MB,文件为400MB,包含20行浮动列的1M行

DataFrame(randn(1000000,20)).to_hdf('test.h5','df')

!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug  6 16:57 test.h5

当写为二进制HDF5文件时更紧凑

In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')

In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug  6 16:58 test.h5

数据是随机的,因此压缩不会太多

答案 3 :(得分:24)

我想我会为讨论带来更多数据。

我对这个问题进行了一系列测试。

通过使用python resource包,我得到了我的进程的内存使用情况。

通过将csv写入StringIO缓冲区,我可以轻松地以字节为单位测量它的大小。

我进行了两次实验,每次实验创建了20个数据帧,这些数据帧的大小在10,000行和1,000,000行之间。两者都有10列。

在第一个实验中,我只在我的数据集中使用了浮点数。

这是与csv文件相比内存增加的方式,作为行数的函数。 (大小以兆字节为单位)

Memory and CSV size in Megabytes as a function of the number of rows with float entries

第二个实验我有相同的方法,但数据集中的数据只包含短字符串。

Memory and CSV size in Megabytes as a function of the number of rows with string entries

似乎csv的大小和数据帧的大小之间的关系可以变化很大,但是内存中的大小总是会大2-3倍(对于这个实验中的帧大小) )

我希望通过更多实验来完成这个答案,如果你想让我尝试一些特别的东西,请发表评论。

答案 4 :(得分:10)

如果您知道数组的dtype,那么您可以直接计算存储数据所需的字节数+一些Python对象本身的字节数。 numpy数组的有用属性为nbytes。您可以通过执行

从pandas DataFrame中的数组中获取字节数
nbytes = sum(block.values.nbytes for block in df.blocks.values())

object dtype数组每个对象存储8个字节(对象dtype数组存储指向不透明PyObject的指针),因此如果csv中有字符串,则需要考虑{{1将它们转换为read_csv dtype数组并相应地调整计算。

编辑:

有关object object的详细信息,请参阅numpy scalar types page。由于只存储了引用,因此您还需要考虑数组中对象的大小。正如该页面所说,对象数组有点类似于Python dtype对象。

答案 5 :(得分:8)

是的。 Pandas会将您的数据存储在由dtypes对它们进行分组的2维numpy ndarray结构中。 ndarray基本上是一个带有小标题的原始C数组。因此,您只需将其包含的dtype的大小乘以数组的维度即可估算其大小。

例如:如果您有1000行,其中包含2个np.int32和5个np.float64列,那么您的DataFrame将包含一个2x1000 np.int32数组和一个5x1000 np.float64数组:

4bytes * 2 * 1000 + 8bytes * 5 * 1000 = 48000字节

答案 6 :(得分:6)

我相信这给了python中任何对象的内存大小。需要检查关于熊猫和numpy

的内部结构
>>> import sys
#assuming the dataframe to be df 
>>> sys.getsizeof(df) 
59542497