如何在Pandas DataFrame中仅对年月命名的列进行排序?
对Pandas DataFrame中年月格式列排序的实现方案
要实现仅对「年月」格式命名的列排序,同时保留其他列的原有顺序,可按以下步骤操作:
1. 自动识别年月格式列
由于不同股票的列存在差异,不能硬编码列名,可通过两种方式自动筛选目标列:
方式一:日期转换验证
遍历所有列名,尝试按「英文月份缩写+空格+四位年份」格式转换为日期,转换成功的即为目标列:
import pandas as pd date_cols = [] for col in df.columns: try: pd.to_datetime(col, format='%b %Y') date_cols.append(col) except ValueError: continue
方式二:正则表达式匹配
用正则表达式匹配符合格式的列名:
import re pattern = r'^[A-Z][a-z]{2} \d{4}$' date_cols = [col for col in df.columns if re.match(pattern, col)]
2. 对年月列按日期顺序排序
将识别出的列名转换为日期对象,以此为依据排序:
sorted_date_cols = sorted(date_cols, key=lambda x: pd.to_datetime(x, format='%b %Y'))
3. 重构DataFrame列顺序
保留非年月列的原有顺序,后续拼接排序后的年月列:
non_date_cols = [col for col in df.columns if col not in date_cols] df_sorted = df[non_date_cols + sorted_date_cols]
完整示例代码
结合你提供的DataFrame,完整可运行代码如下:
import pandas as pd import re # 构造示例数据 data = { 'Quarterly Results': ['Sales', 'Expenses', 'Operating Profit', 'OPM %', 'Other Income'], 'Stockname': ['526433']*5, 'Mar 2021': [40.8, 36.78, 4.02, '9.85%', 0.7], 'Jun 2021': [41.64, 36.7, 4.94, '11.86%', 0.5], 'Sep 2021': [47.7, 39.98, 7.72, '16.18%', 0.35], 'Dec 2021': [47.62, 42.3, 5.32, '11.17%', 3.89], 'Dec 2022': [54.14, 48.94, 5.2, '9.60%', 2.74], 'Mar 2023': [51.94, 49.74, 2.2, '4.24%', 1.55], 'Jun 2023': [50.95, 48.58, 2.37, '4.65%', 1.98], 'Sep 2023': [50.39, 48.46, 1.93, '3.83%', 0.42], 'Mar 2022': [54.71, 51.69, 3.02, '5.52%', 2.19], 'Jun 2022': [50.92, 45.54, 5.38, '10.57%', 2.43], 'Sep 2022': [63.42, 57.43, 5.99, '9.44%', 1.58] } df = pd.DataFrame(data) # 识别年月列 pattern = r'^[A-Z][a-z]{2} \d{4}$' date_cols = [col for col in df.columns if re.match(pattern, col)] # 排序年月列 sorted_date_cols = sorted(date_cols, key=lambda x: pd.to_datetime(x, format='%b %Y')) # 重新排列列 non_date_cols = [col for col in df.columns if col not in date_cols] df_sorted = df[non_date_cols + sorted_date_cols] # 输出排序后的列名 print(df_sorted.columns)
运行后,列将按如下顺序排列:['Quarterly Results', 'Stockname', 'Mar 2021', 'Jun 2021', 'Sep 2021', 'Dec 2021', 'Mar 2022', 'Jun 2022', 'Sep 2022', 'Dec 2022', 'Mar 2023', 'Jun 2023', 'Sep 2023']
关键说明
- 两种识别方法均无需硬编码列名,可适配不同股票的列差异。
- 通过
pd.to_datetime转换列名实现排序,确保跨年度的列排序逻辑准确。
内容的提问来源于stack exchange,提问作者RSW
相关产品推荐
相关产品推荐

