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

如何用Python Pandas的pivot和melt转换指定DataFrame?

问题:用Pandas实现指定的DataFrame格式转换

原始DataFrame如下:

date     price num_floors    house
0  2023-01-01  94.30076          3        A
1  2023-01-01  95.58771          2        B
2  2023-01-02 102.78559          1        C
3  2023-01-03  93.29053          3        D

希望转换为以下格式:每列对应一个日期,列内前两行对应第一套房屋的price和num_floors,接下来两行对应第二套房屋,无数据位置用NaN填充:

2023-01-01  2023-01-02  2023-01-03
1    94.30076   102.78559    93.29053
2     3.00000     1.00000     3.00000
3    95.58771         NaN         NaN
4     2.00000         NaN         NaN

已用R实现该转换,代码如下:

df_trans <- df %>%
    pivot_longer(-date) %>%  # 注:实际应排除house列,否则会引入无效数据
    mutate(index=row_number(), .by = date) %>%
    pivot_wider(id_cols = index, names_from = date, values_from = value) %>%
    select(-index)

尝试用Python实现时未得到预期结果,Python代码如下:

df_trans = df.melt(id_vars='date')
df_trans['n'] = df_trans.groupby('date').cumcount() + 1
df_trans = df_trans.pivot(index='n', columns='date', values='value')

解决方案

你的Python代码核心问题是没有排除house列,导致melt后引入了不需要的房屋名称数据,使得cumcount生成的索引完全偏离预期。以下是修正后的代码,完全对齐R代码的逻辑:

import pandas as pd

# 构造原始DataFrame(如果已有数据可跳过此步)
df = pd.DataFrame({
    'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-03'],
    'price': [94.30076, 95.58771, 102.78559, 93.29053],
    'num_floors': [3, 2, 1, 3],
    'house': ['A', 'B', 'C', 'D']
})

# 1. 移除不需要的house列,只保留待转换的字段
df_clean = df.drop('house', axis=1)

# 2. 宽转长:将price和num_floors转为长格式
df_long = df_clean.melt(id_vars='date', var_name='attr', value_name='value')

# 3. 按日期分组,生成组内连续索引(对应目标格式的行号)
df_long['row_idx'] = df_long.groupby('date').cumcount() + 1

# 4. 长转宽:按行索引分组,日期作为列
df_trans = df_long.pivot(index='row_idx', columns='date', values='value')

# 5. 调整显示格式:移除列名层级、索引名称
df_trans.columns.name = None
df_trans.index.name = None

print(df_trans)

代码说明

  • 移除house列:目标格式不需要房屋名称,必须先剔除该列,避免干扰后续转换逻辑
  • melt指定字段:仅对price和num_floors做宽转长,保证长格式数据仅包含需要的属性值
  • 组内生成索引:groupby('date').cumcount() +1和R中row_number(), .by = date逻辑完全一致,给每个日期下的行分配从1开始的连续编号
  • 透视转换:以生成的行索引为基准,将日期转为列,得到目标格式;最后调整显示格式,和示例输出对齐

运行后输出将完全符合预期,空值显示为Pandas默认的NaN,和示例中的NA等价。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:09:59