在Pandas中展开矩阵:现有循环代码的优化方案问询
更高效的矩阵转长表方法
当然有!Pandas 内置了专门处理这类宽表转长表的工具,比你写的嵌套循环高效得多,代码也更简洁易读,尤其适合处理大规模数据。
方法一:使用 stack()(最简洁直接)
这是处理矩阵转长表最直观的方式,利用 Pandas 的层级索引操作一键完成转换:
import pandas as pd # 原始矩阵 DataFrame df = pd.DataFrame({'a':[7, 0, 3], 'b':[0, 4, 2], 'c':[3, 2, 9]}) df.index = list(df) # 转换为长表 long_df = df.stack().reset_index() long_df.columns = ['C1', 'C2', 'V']
运行后得到的结果完全符合你的需求:
C1 C2 V 0 a a 7 1 a b 0 2 a c 3 3 b a 0 4 b b 4 5 b c 2 6 c a 3 7 c b 2 8 c c 9
原理说明:
stack()会把 DataFrame 的列索引“堆叠”为内层行索引,生成一个带多级索引的 Series;reset_index()把多级索引转换为普通列;- 最后重命名列名即可,而且
V列的类型默认就是整数,不需要额外转换。
方法二:使用 melt() 函数
如果你更习惯用“宽表转长表”的通用思路,也可以用 melt() 实现:
import pandas as pd df = pd.DataFrame({'a':[7, 0, 3], 'b':[0, 4, 2], 'c':[3, 2, 9]}) df.index = list(df) # 先把原索引转为普通列 df = df.reset_index(names='C1') # 用 melt 转换 long_df = df.melt(id_vars='C1', var_name='C2', value_name='V')
这个方法先把原来的行索引(a/b/c)转为列C1,再通过melt()将原来的列名作为C2列,对应的值存入V列,结果和上面完全一致。
为什么比循环更好?
- 效率更高:Pandas 的内置函数是基于底层 C 语言实现的,远快于 Python 级别的嵌套循环,当你的矩阵规模变大(比如1000×1000)时,差距会非常明显;
- 代码更简洁:几行代码就能完成循环十几行的工作,可读性更强,也减少了手动维护索引
i的出错概率; - 原生支持类型保持:不需要额外手动转换
V列的类型,内置函数会自动保留原始数据类型。
内容的提问来源于stack exchange,提问作者Fernando S. Peregrino
相关产品推荐
相关产品推荐

