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

如何基于指定行首个非零值重排Pandas DataFrame

问题描述

现有一个记录不同开业时间店铺的销售、成本数据的Pandas DataFrame,列是月份。需要基于各店铺Sales行首个非零值所在月份重排列,使列顺序变为开业后第1个销售月、第2个销售月……以便统一对比各店铺的首月及后续业绩。

示例原始数据(修正后可运行版本):

import pandas as pd

data = [
    ['Store 1', 'Sales', 0.0, 0.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
    ['Store 1', 'Costs', 0.0, 0.0, 0.0, 3.0, 1.0, 1.0, 7.0, 0.0],
    ['Store 2', 'Sales', 0.0, 0.0, 0.0, 0.0, 15.0, 16.0, 17.0, 18.0]
]
columns = ['Store', 'Metric', 'Jan-19', 'Feb-19', 'Mar-19', 'Apr-19', 'May-19', 'June-19', 'Jul-19', 'Aug-19']
df = pd.DataFrame(data, columns=columns)
df = df.set_index(['Store', 'Metric'])

期望重排后效果:

A     B     C     D     E     F
Store 1 Sales  3.0   4.0   5.0   6.0   7.0   8.0
Store 1 Costs  0.0   3.0   1.0   1.0   7.0   0.0
Store 2 Sales 15.0  16.0  17.0  18.0   NaN   NaN
解决思路与代码

核心思路是按店铺分组,找到每个店铺Sales行的首个非零列位置,然后从该位置开始截取所有后续列,最后统一重命名列名。

步骤1:定义分组处理函数

def align_store_columns(group):
    # 提取当前店铺的Sales行数据
    sales_row = group.xs('Sales', level='Metric')
    # 找到首个非零值对应的列索引
    first_non_zero_col = sales_row.ne(0).idxmax()
    # 从该列开始截取所有后续列
    aligned_data = group.loc[:, first_non_zero_col:]
    # 将列名重命名为A、B、C...
    aligned_data.columns = [chr(ord('A') + i) for i in range(len(aligned_data.columns))]
    return aligned_data

步骤2:分组应用并合并结果

# 按店铺分组处理,合并结果
result = df.groupby('Store', group_keys=False).apply(align_store_columns)
# 重置索引(可选,方便查看结构化数据)
result = result.reset_index()

print(result)

代码说明

  • sales_row.ne(0).idxmax():ne(0)生成布尔数组(非零为True),idxmax()返回第一个True对应的列名,即首个有销售数据的月份。
  • 按店铺分组后,每个店铺的所有指标(Sales、Costs等)都从该月份开始截取,保证同一店铺的指标列对齐到开业后的时间节点。
  • 列名重命名为A、B、C...,实现不同店铺的首月、次月数据统一列名对比。
补充说明

你之前尝试的代码是获取首个非零值,而我们需要的是该值所在的列位置,这是实现列重排的关键——只有找到起始列,才能截取后续的月份数据完成对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:41:34