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

Pandas宽格式数据:提取各图书最早两个季度的有效销售数据

处理宽格式DataFrame:提取每本图书最早两个有数据的季度销售数据

问题背景

现有宽格式销售数据DataFrame,记录不同图书的季度销量,未发布季度以0填充。需要为每本图书提取最早的两个有有效销量的季度,并将对应数据存入新DataFrame的两列中。

示例数据

import pandas as pd

data = {'Book Title': ['A Court of Thorns and Roses', 'Where the Crawdads Sing', 'Bad Blood', 'Atomic Habits'],
    'Metric': ['Book Sales','Book Sales','Book Sales','Book Sales'],
   'Q1 2022': [100000,0,0,0],
   'Q2 2022': [50000,75000,0,35000],
   'Q3 2022': [25000,150000,20000,45000],
   'Q4 2022': [25000,20000,10000,65000]}

df1 = pd.DataFrame(data)

实现步骤与代码

1. 转换为长格式数据

把宽格式的季度列转为行结构,方便按图书分组处理:

# 保留图书名称和度量列,将季度列转为长格式
df_long = df1.melt(id_vars=['Book Title', 'Metric'], var_name='Quarter', value_name='Sales')

2. 过滤无效数据并按季度排序

过滤掉销量为0的无效行,再按图书分组,对每个组的季度按时间顺序排序,取前两个有效记录:

# 过滤销量为0的行
df_filtered = df_long[df_long['Sales'] != 0]

# 按图书分组,对每组的季度排序后取前两个
# 注:Q1/Q2/Q3/Q4+年份的字符串格式天然有序,可直接排序
df_top2 = df_filtered.groupby('Book Title').apply(lambda x: x.sort_values('Quarter').head(2)).reset_index(drop=True)

3. 转换回宽格式生成目标DataFrame

把每个图书的前两个季度数据转为两列,让结果更直观:

# 给每个图书的有效季度添加序号(第1/2个)
df_top2['Rank'] = df_top2.groupby('Book Title').cumcount() + 1

# 转换为宽格式
result_df = df_top2.pivot(index=['Book Title', 'Metric'], columns='Rank', values=['Quarter', 'Sales']).reset_index()

# 重命名列名
result_df.columns = ['Book Title', 'Metric', 'First Quarter', 'Second Quarter', 'First Sales', 'Second Sales']

4. 查看最终结果

print(result_df)

输出示例:

Book Title      Metric First Quarter Second Quarter  First Sales  Second Sales
0                  Atomic Habits  Book Sales      Q2 2022       Q3 2022        35000         45000
1                      Bad Blood  Book Sales      Q3 2022       Q4 2022        20000         10000
2  A Court of Thorns and Roses  Book Sales      Q1 2022       Q2 2022       100000         50000
3     Where the Crawdads Sing  Book Sales      Q2 2022       Q3 2022        75000        150000

注意事项

  • 如果原始数据的空值是NaN而非0,只需把过滤条件改成df_long[df_long['Sales'].notna()]
  • 若季度格式不是Qx YYYY,需先转为时间格式再排序,示例代码:
    df_filtered['Quarter'] = pd.to_datetime(df_filtered['Quarter'].str.replace('Q', ''), format='%m %Y')
    
    排序后可再转回原字符串格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:15:37