Python DataFrame内存存储机制及新增行列的性能差异疑问
Pandas DataFrame存储与行列新增操作说明
底层内存存储逻辑
Pandas的DataFrame采用按列存储的结构,本质是一个存储多个Series对象的有序字典:
- 每一列对应一个独立的Series实例,每个Series底层是固定类型的NumPy数组
- 不同列的NumPy数组可以是不同数据类型,以此实现不同列存储异构数据的需求
- 所有列的元数据(列名、数据类型等)统一由DataFrame维护,不需要修改列数据本身就能快速调整列的顺序、增删列
新增列与新增行的内存操作细节
新增一列
操作本质是往列存储的字典里新增一组键值对,内存层面仅需要做三件事:
- 分配一块连续内存,存储新列的n个元素
- 将新列的引用、列名、数据类型更新到DataFrame的元数据中
- 原有所有列的内存数据完全不需要改动,也不会发生拷贝
新增一行
因为底层是按列存储,新增一行需要修改所有已有列的内容,而NumPy数组是固定长度的连续内存结构,无法直接在原有内存地址后追加元素,因此内存层面需要完成的操作是:
- 遍历DataFrame的所有n个列,给每个列重新分配一块可容纳n+1个元素的新连续内存
- 将每个列原有n个元素拷贝到新分配的内存地址
- 把新行对应每个列的元素写入各列新内存的最后位置
- 更新所有列的引用、DataFrame的行计数等元数据
耗时对比
对于规模较大的n*n DataFrame,新增一行的耗时远高于新增一列:
新增一列的时间复杂度是O(n),仅和行数相关;新增一行的时间复杂度是O(n²),需要对n个列各做一次O(n)的拷贝操作,n越大两者的耗时差距越明显。
小提示:如果业务场景需要频繁新增多行,不要循环调用
append或者loc新增行,建议先把所有行数据暂存在Python列表中,最后一次性转换为DataFrame,可大幅降低性能开销。
内容的提问来源于stack exchange,提问作者nan
相关产品推荐
相关产品推荐

