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

如何调整Pandas pivot_table实现指定格式的DataFrame转换?

Pandas DataFrame多重复行透视转换解决方案

原始数据

import pandas as pd

data = [
    {'column1': 'asd', 'column2': 'a', 'column3': 'mileage', 'column4': 7889, 'column5': None},
    {'column1': 'fsd', 'column2': 'a', 'column3': 'temp', 'column4': 4557, 'column5': None},
    {'column1': None, 'column2': 'a', 'column3': 'string', 'column4': None, 'column5': 'value_string1'},
    {'column1': 'asd', 'column2': 'b', 'column3': 'mileage', 'column4': 5678, 'column5': None},
    {'column1': 'fsd', 'column2': 'b', 'column3': 'temp', 'column4': 5830, 'column5': None},
    {'column1': None, 'column2': 'b', 'column3': 'string', 'column4': None, 'column5': 'value_string2'},
    {'column1': None, 'column2': 'c', 'column3': 'temp', 'column4': 10, 'column5': None},
    {'column1': None, 'column2': 'c', 'column3': 'temp', 'column4': 8, 'column5': None},
]

df = pd.DataFrame(data)

期望输出

column2 mileage temp_1  temp_2  
a       7889.0  4557.0  NaN
b       5678.0  5830.0  NaN
c        NaN    10.0    NaN
c        NaN     NaN    8.0

现有问题

直接使用pivot_table会自动对column2和column3相同的行做平均值聚合,丢失原始行的独立信息:

pivot_table = df.pivot_table(index='column2', columns='column3', values='column4')

输出结果:

column3 mileage temp
column2     
a       7889.0  4557.0
b       5678.0  5830.0
c         NaN    9.0

解决方案

核心思路是为同组内的重复项添加唯一序号,避免透视时被聚合,以下是两种可行方法:

方法一:结合cumcount与pivot

# 筛选有效数据:排除column3为string的行,保留column4非空的记录
df_process = df[(df['column3'] != 'string') & df['column4'].notna()].copy()

# 为每个(column2, column3)分组添加组内序号
df_process['seq'] = df_process.groupby(['column2', 'column3']).cumcount() + 1

# 构造新列名:重复项添加序号,非重复项保留原名
df_process['new_col'] = df_process.apply(
    lambda x: f"{x['column3']}_{x['seq']}" if x['seq'] > 1 else x['column3'],
    axis=1
)

# 透视:用column2和seq作为联合索引,确保重复项不会被合并
result = df_process.pivot(
    index=['column2', 'seq'],
    columns='new_col',
    values='column4'
).reset_index(level=1, drop=True).reset_index()

# 调整列顺序,匹配期望输出
final_df = result[['column2', 'mileage', 'temp_1', 'temp_2']]
print(final_df)

方法二:简化版处理

df_process = df[(df['column3'] != 'string') & df['column4'].notna()].copy()

# 生成组内序号
df_process['row_num'] = df_process.groupby(['column2', 'column3']).cumcount()

# 构造带序号的列名,mileage直接保留原名
df_process['col_name'] = df_process['column3']
df_process.loc[df_process['column3'] == 'temp', 'col_name'] = 'temp_' + (df_process['row_num'] + 1).astype(str)

# 透视并整理格式
result = df_process.pivot(
    index=['column2', 'row_num'],
    columns='col_name',
    values='column4'
).reset_index(level=1, drop=True).reset_index()[['column2', 'mileage', 'temp_1', 'temp_2']]

print(result)

两种方法都能得到符合要求的输出,保留原始行的独立数据,不会自动聚合重复项。


内容的提问来源于stack exchange,提问作者Mingian101

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:00:45