如何加速创建包含不同形状ndarray的Pandas DataFrame
缓慢原因
耗时问题和Pandas DataFrame构造器的默认逻辑直接相关:
传入嵌套列表作为构造输入时,Pandas不会直接将输入的ndarray识别为单个单元格的值,而是会自动执行全列类型推断、维度对齐与数组拼接校验:它会尝试把同列下的所有元素(你的4维大数组、其余行的标量数值)合并为一个维度统一的同构numpy数组。
这个校验过程需要遍历你传入的(100,100,20,2)数组的全部元素做兼容性判断,总耗时和数组元素总量正相关,这就是50秒耗时的来源。单独运行np.random.rand仅做内存分配与随机数填充,没有这层遍历校验逻辑,所以速度极快。
加速方案
核心思路是主动跳过Pandas的自动同构数组推断逻辑,强制将单元格值作为object类型存储,以下三种方案均可把创建耗时压缩到毫秒级:
- 方案1:先初始化空DataFrame再赋值
先创建带指定索引、列名的空DataFrame,显式声明dtype=object,后续再逐单元格/逐块赋值,完全跳过初始构造时的全量校验:import numpy as np import pandas as pd x = pd.DataFrame( index=['A1', 'B2', 'C3', 'D4'], columns=['data', 'data2'], dtype=object ) # 存入大ndarray和标量值 x.loc['A1', 'data'] = np.random.rand(100, 100, 20, 2) x.loc['A1', 'data2'] = 3 x.loc['B2':, :] = [[2,2], [3,3], [4,4]] - 方案2:按列组织数据+显式指定object类型
构造时直接传入按列组织的字典,显式指定dtype=object,告诉Pandas不需要做数组广播拼接:import numpy as np import pandas as pd x = pd.DataFrame( { 'data': [np.random.rand(100, 100, 20, 2), 2, 3, 4], 'data2': [3, 2, 3, 4] }, index=['A1', 'B2', 'C3', 'D4'], dtype=object ) - 方案3:先构造单列Series再拼接
形状不统一的元素构造为Series时会自动存为object类型,不会触发维度校验,最后按列拼接为DataFrame即可:import numpy as np import pandas as pd data_col = pd.Series([np.random.rand(100, 100, 20, 2), 2, 3, 4], index=['A1', 'B2', 'C3', 'D4'], dtype=object) data2_col = pd.Series([3, 2, 3, 4], index=['A1', 'B2', 'C3', 'D4'], dtype=object) x = pd.concat([data_col, data2_col], axis=1, keys=['data', 'data2'])
注意:存储任意形状ndarray的DataFrame列本质是object类型,无法使用Pandas自带的向量化数值运算逻辑,如需做批量数组计算建议单独对单元格内的ndarray做遍历处理。
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

