如何将含字符串数组的DataFrame高效转换为Pandas多级索引?
高效转换字符串数组列为多级索引DataFrame的方法
核心思路
利用pandas的矢量化操作(explode)替代逐行apply,先将字符串格式的数组转为列表,再拆分每个列表为多行,最后合并各列并构建多级索引。这种方法避免了Python级别的循环,能大幅提升大数据量下的处理效率。
实现步骤与代码
1. 导入依赖并准备数据
import pandas as pd import ast # 示例数据 d = { 'col1': ['[5.02, 1, 3, 2]', '[2.002, 3.14, 4.5, 6.000153, 3]'], 'col2': ['[1.01, 1.02, 2, 4, 5, 10]', '[2, 3.05, 4.001, 7]'], 'col3': [5.2, 3] } df = pd.DataFrame(d)
2. 字符串转列表(高效方案)
提供两种高效转换方式,根据数据格式选择:
- 方案A(安全通用):用
ast.literal_eval解析字符串数组,适合格式标准的数组字符串:
df['col1'] = df['col1'].apply(ast.literal_eval) df['col2'] = df['col2'].apply(ast.literal_eval)
- 方案B(更快,适合纯数值数组):用正则表达式提取数值,速度比
ast.literal_eval更优,适合数据量极大的场景:
df['col1'] = df['col1'].str.findall(r'-?\d+\.?\d*').apply(lambda x: [float(i) for i in x]) df['col2'] = df['col2'].str.findall(r'-?\d+\.?\d*').apply(lambda x: [float(i) for i in x])
3. 拆分列表为多行并构建索引
# 为原数据添加dataset索引(对应原行号) df = df.reset_index().rename(columns={'index': 'dataset'}) # 拆分col1并生成data point索引 col1_expanded = df.explode('col1', ignore_index=False).reset_index(drop=True) col1_expanded['data point'] = col1_expanded.groupby('dataset').cumcount() # 拆分col2并生成data point索引 col2_expanded = df.explode('col2', ignore_index=False).reset_index(drop=True) col2_expanded['data point'] = col2_expanded.groupby('dataset').cumcount() # 处理col3:为每个dataset的所有data point重复对应值 max_points = pd.concat( [col1_expanded.groupby('dataset')['data point'].max(), col2_expanded.groupby('dataset')['data point'].max()], axis=1 ).max(axis=1) col3_expanded = df[['dataset', 'col3']].reindex(df.index.repeat(max_points + 1)) col3_expanded['data point'] = col3_expanded.groupby('dataset').cumcount() # 合并所有列并设置多级索引 result = pd.merge( col1_expanded[['dataset', 'data point', 'col1']], col2_expanded[['dataset', 'data point', 'col2']], on=['dataset', 'data point'], how='outer' ) result = pd.merge( result, col3_expanded[['dataset', 'data point', 'col3']], on=['dataset', 'data point'], how='outer' ).set_index(['dataset', 'data point']).sort_index()
运行后得到的result即为期望的多级索引DataFrame。
效率优化建议
- 优先使用矢量化操作:
explode是pandas内置的矢量化函数,底层由C实现,比自定义apply循环效率高10~100倍(数据量越大差距越明显)。 - 内存优化:转换后确保
col1、col2为float类型(若之前转的是float列表则无需额外操作),避免object类型占用过多内存。 - 批量处理:若数据量超大(百万行以上),可分批次处理后再合并,避免内存溢出。
内容的提问来源于stack exchange,提问作者Bernd Steinhauser
相关产品推荐
相关产品推荐

