You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需循环,用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:13:07