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

如何对Pandas DataFrame按Table分组、组内时序排序并按组首条时间排序?

处理DataFrame分组、组内排序及按分组起始时间排序需求

问题背景

现有如下格式的DataFrame(Date列格式为DD-MM-YYYY):

Date        Time      Table
01-10-2000  13:00:03  B
01-10-2000  13:00:04  A
01-10-2000  13:00:05  B
01-10-2000  13:00:06  A
01-10-2000  13:00:07  B
01-10-2000  13:00:08  A

需要完成三个操作:

  • 按Table列分组
  • 每个分组内按Date和Time列排序
  • 按照每个分组第一条记录的Date+Time时间顺序,重新排列分组的展示顺序

期望输出:

Date        Time      Table
01-10-2000  13:00:03  B
01-10-2000  13:00:05  B
01-10-2000  13:00:07  B
01-10-2000  13:00:04  A
01-10-2000  13:00:06  A
01-10-2000  13:00:08  A

输入数据的初始化代码:

import pandas as pd

data = {
    'Date': ['01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000'],
    'Time': ['13:00:03', '13:00:04', '13:00:05', '13:00:06', '13:00:07', '13:00:08'],
    'Table': ['B', 'A', 'B', 'A', 'B', 'A']
}
df = pd.DataFrame(data)

解决方案

步骤1:合并日期时间列并转换为datetime类型

为了避免字符串排序的误差,先将Date和Time合并为完整的datetime列,同时指定原始日期格式确保解析正确:

df['datetime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], format='%d-%m-%Y %H:%M:%S')

步骤2:分组并完成组内排序

按Table分组后,对每个分组内的行按datetime列排序:

grouped = df.groupby('Table', group_keys=False).apply(lambda x: x.sort_values('datetime'))

步骤3:按分组的起始时间重新排序分组

提取每个分组第一条记录的datetime值,以此为依据对分组进行排序:

# 获取每个分组的最早时间并生成排序后的分组索引
group_order = grouped.groupby('Table')['datetime'].first().sort_values().index

# 按指定顺序重新排列分组
result = grouped.set_index('Table').loc[group_order].reset_index()

整理最终结果(移除临时列)

如果不需要保留临时的datetime列,可执行以下代码调整:

# 调整列顺序并移除临时列
result = result[['Date', 'Time', 'Table']].drop('datetime', axis=1)
print(result)

输出结果与期望完全一致:

Date      Time Table
0  01-10-2000  13:00:03     B
1  01-10-2000  13:00:05     B
2  01-10-2000  13:00:07     B
3  01-10-2000  13:00:04     A
4  01-10-2000  13:00:06     A
5  01-10-2000  13:00:08     A

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:34:53