我们可以看到它有 171907 行和 161 列。pandas 已经为我们自动检测了数据类型,其中包
括 83 列数值型数据和 78 列对象型数据。对象型数据列用于字符串或包含混合数据类型的
列。
由此我们可以进一步了解我们应该如何减少内存占用,下面我们来看一看 pandas 如何在
内存中存储数据。
Dataframe 对象的内部表示¶
在底层,pandas 会按照数据类型将列分组形成数据块(blocks)。下图所示为 pandas 如
何存储我们数据表的前十二列:
可以注意到,这些数据块没有保持对列名的引用,这是由于为了存储 dataframe 中的真实
数据,这些数据块都经过了优化。有个 BlockManager 类会用于保持行列索引与真实数据
块的映射关系。他扮演一个 API,提供对底层数据的访问。每当我们查询、编辑或删除数
据时,dataframe 类会利用 BlockManager 类接口将我们的请求转换为函数和方法的调用。
每种数据类型在 pandas.core.internals 模块中都有一个特定的类。pandas 使用
ObjectBlock 类来表示包含字符串列的数据块,用 FloatBlock 类来表示包含浮点型列的数
据块。对于包含数值型数据(比如整型和浮点型)的数据块,pandas 会合并这些列,并把
它们存储为一个 Numpy 数组(ndarray)。Numpy 数组是在 C 数组的基础上创建的,其值
在内存中是连续存储的。基于这种存储机制,对其切片的访问是相当快的。
由于不同类型的数据是分开存放的,我们将检查不同数据类型的内存使用情况,我们先看
看各数据类型的平均内存使用量:
for dtype in ['float','int','object']:
selected_dtype = gl.select_dtypes(include=[dtype])
mean_usage_b = selected_dtype.memory_usage(deep=True).mean()
mean_usage_mb = mean_usage_b / 1024 ** 2
print("Average memory usage for {} columns: {:03.2f}
MB".format(dtype,mean_usage_mb))
Average memory usage for float columns: 1.29 MB
Average memory usage for int columns: 1.12 MB
Average memory usage for object columns: 9.53 MB
我们可以看到内存使用最多的是 78 个 object 列,我们待会再来看它们,我们先来看看我
们能否提高数值型列的内存使用效率。