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

在Pandas DataFrame中按Part聚类、Date子聚类排序Quantity(正值优先)

Pandas按子聚类排序:正值前置的实现方案

问题背景

现有如下Pandas DataFrame:

Part  Date         Quantity
A     2023-10-26   -1
A     2023-10-26    1
A     2023-11-03    1
A     2023-12-15   -1
B     2023-11-09    2
B     2023-11-14   -2
B     2023-11-14    2
B     2023-11-19    2

要求:以Part为一级分组,Date为二级子分组,每个子分组内把Quantity的正值放在前面,最终要得到这样的结果:

Part  Date         Quantity
A     2023-10-26    1
A     2023-10-26   -1
A     2023-11-03    1
A     2023-12-15   -1
B     2023-11-09    2
B     2023-11-14    2
B     2023-11-14   -2
B     2023-11-19    2

解决方案

完全没必要用双重groupby,用sort_values就能简单高效搞定,甚至不需要额外临时列。当然如果非要用groupby也能实现,但属于画蛇添足。

最优方案:直接用sort_values排序

import pandas as pd

# 构造原始数据(已有DataFrame可跳过此步)
df = pd.DataFrame({
    'Part': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
    'Date': ['2023-10-26', '2023-10-26', '2023-11-03', '2023-12-15',
             '2023-11-09', '2023-11-14', '2023-11-14', '2023-11-19'],
    'Quantity': [-1, 1, 1, -1, 2, -2, 2, 2]
})

# 核心排序逻辑
df_sorted = df.sort_values(
    by=['Part', 'Date', df['Quantity'] > 0, 'Quantity'],
    ascending=[True, True, False, True]
)

# 可选:重置索引,消除原索引干扰
df_sorted = df_sorted.reset_index(drop=True)

print(df_sorted)

逻辑说明

  • df['Quantity'] > 0会生成布尔序列,正值对应True(排序时视为1),负值对应False(视为0),设置ascending=False后,1会排在0前面,实现正值前置。
  • 最后加'Quantity'排序是为了保证同符号数值按大小排列,可根据需求选择保留或删除。

备选方案:用groupby实现(不推荐)

如果一定要用groupby,可以这么写,但步骤更繁琐:

df_sorted = df.groupby(['Part', 'Date'], group_keys=False).apply(
    lambda x: x.sort_values(by='Quantity', key=lambda y: y < 0)
)

逻辑说明

  • 按Part和Date分组后,对每个子分组用sort_values,排序key用lambda y: y < 0——负值返回True(1),正值返回False(0),排序后0在前,即正值排在前面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:17:31