如何在Pandas中对DATE_TIME列实现从12点起始的自定义排序
自定义DATE_TIME列排序:从12:00开始到11:59结束
问题背景
我有如下数据集:
import random import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import matplotlib.ticker as ticker random.seed(0) df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-06 23:00:00', freq='20min'), 'ID': [random.randrange(1, 3) for n in range(430)]}) df['VALUE1'] = [random.uniform(110, 160) for n in range(430)] df['VALUE2'] = [random.uniform(50, 80) for n in range(430)] df['INSPECTION'] = df['DATE_TIME'].dt.day # df['INSPECTION'] = df['INSPECTION'].replace(6, 1) # df['INSPECTION'] = df['INSPECTION'].replace(3, 1) df['MODE'] = np.select([df['INSPECTION'] == 1, df['INSPECTION'].isin([2, 3])], ['A', 'B'], 'C') df['TIME'] = df['DATE_TIME'].dt.time df['TIME'] = df['TIME'].astype('str') df['TIMEINTERVAL'] = df.DATE_TIME.diff().astype('timedelta64[m]') df['TIMEINTERVAL'] = df['TIMEINTERVAL'].fillna(0) def to_day_period(s): bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00'] labels = ['Nighttime', 'Daytime', 'Daytime', 'Nighttime', 'Nighttime'] return pd.cut( pd.to_timedelta(s), bins=list(map(pd.Timedelta, bins)), labels=labels, right=False, ordered=False ) df['TIME_OF_DAY'] = to_day_period(df['TIME']) df_monthly = df
我需要对ID=1且INSPECTION=1的数据,按DATE_TIME列进行自定义排序:让时间从12:00:00开始,到次日11:59:59结束。尝试过将DATE_TIME偏移12小时后用np.argsort处理,但没成功。
示例数据
针对ID=1且INSPECTION=1的情况,现有数据:
| DATE_TIME | VALUE1 |
|---|---|
| 2022-11-01 00:00:00 | 55 |
| 2022-11-01 11:00:00 | 45 |
| 2022-11-01 12:00:00 | 40 |
| 2022-11-01 22:00:00 | 35 |
| 2022-11-01 23:00:00 | 70 |
期望结果
排序后的数据:
| DATE_TIME | VALUE1 |
|---|---|
| 2022-11-01 12:00:00 | 40 |
| 2022-11-01 22:00:00 | 35 |
| 2022-11-01 23:00:00 | 70 |
| 2022-11-01 00:00:00 | 55 |
| 2022-11-01 11:00:00 | 45 |
解决方案
核心思路是基于时间的小时数生成排序键:12:00及之后的时间用原小时数,12:00之前的时间用小时数+24,这样排序时12-23点会自然排在0-11点前面。
单组数据排序代码
# 筛选目标数据 filtered_df = df[(df['ID'] == 1) & (df['INSPECTION'] == 1)].copy() # 生成排序键:12点前的小时加24,确保排序顺序正确 filtered_df['sort_key'] = filtered_df['DATE_TIME'].dt.hour.apply(lambda x: x if x >= 12 else x + 24) # 按排序键升序排列,删除临时列 sorted_df = filtered_df.sort_values('sort_key').drop('sort_key', axis=1) # 查看结果 print(sorted_df[['DATE_TIME', 'VALUE1']])
多组数据批量排序代码
如果需要对整个数据集按日期、ID、INSPECTION分组后统一应用该排序逻辑:
def sort_by_12h_group(g): # 给每组生成排序键 g['sort_key'] = g['DATE_TIME'].dt.hour.apply(lambda x: x if x >= 12 else x + 24) # 排序后删除临时键 return g.sort_values('sort_key').drop('sort_key', axis=1) # 按日期、ID、INSPECTION分组执行排序 df_sorted = df.groupby([df['DATE_TIME'].dt.date, 'ID', 'INSPECTION'], group_keys=False).apply(sort_by_12h_group)
代码说明
- 筛选目标数据时用
copy()避免修改原DataFrame - 排序键的设计让0-11点的时间被映射为24-35,排序时会排在12-23点(12-23)之后
- 批量排序用
groupby+apply,确保每组内都按自定义规则排序
内容的提问来源于stack exchange,提问作者dsapprentice
相关产品推荐
相关产品推荐

