如何无需循环,用merge/concat实现Pandas交叉表更新?
无循环实现DataFrame结构转换的高效方法
源DataFrame
import pandas as pd data = { 'T1': ['A1', 'A2', 'A3'], 'V1': [10, 5, 7], 'T2': ['A4', 'A3', 'A1'], 'V2': [8, 10, 1], 'T3': ['A2', 'A1', 'A4'], 'V3': [1, 7, 9] } df = pd.DataFrame(data, index=['4/1/2023', '4/2/2023', '4/3/2023'])
输出:
T1 V1 T2 V2 T3 V3 4/1/2023 A1 10 A4 8 A2 1 4/2/2023 A2 5 A3 10 A1 7 4/3/2023 A3 7 A1 1 A4 9
目标DataFrame
A3 A2 A4 A1 4/1/2023 0 1 8 10 4/2/2023 10 5 0 7 4/3/2023 7 0 9 1
无循环实现方案
完全可以用Pandas的矢量化操作替代循环,效率更高,代码更简洁,核心思路是先把数据转成长格式,再透视回宽格式:
# 1. 将索引转为日期列,方便后续处理 df_reset = df.reset_index().rename(columns={'index': 'Date'}) # 2. 拆分T/V配对,转成长格式 melted_data = pd.concat([ # 处理T1-V1配对 df_reset[['Date', 'T1']].rename(columns={'T1': 'Category'}).assign(Value=df_reset['V1']), # 处理T2-V2配对 df_reset[['Date', 'T2']].rename(columns={'T2': 'Category'}).assign(Value=df_reset['V2']), # 处理T3-V3配对 df_reset[['Date', 'T3']].rename(columns={'T3': 'Category'}).assign(Value=df_reset['V3']) ]) # 3. 透视成目标格式,缺失值填充为0,并转为整数类型 result = melted_data.pivot(index='Date', columns='Category', values='Value') \ .fillna(0) \ .astype(int) # 4. 调整列顺序和目标一致(如果需要) result = result[['A3', 'A2', 'A4', 'A1']]
为什么这个方法更好
- 避免了嵌套循环,利用Pandas内部优化的矢量化操作,数据量越大,效率提升越明显;
- 代码逻辑清晰,可读性更强,便于维护和修改;
- 无需手动处理每行每列的匹配逻辑,减少出错概率。
内容的提问来源于stack exchange,提问作者Rajib Lochan Sarkar
相关产品推荐
相关产品推荐

