sort year,month of date

该篇文章展示了如何使用Java通过自定义比较器对日期按年月进行排序,并将它们分组到相应的年月键下。作者提供了一个示例,展示如何处理LocalDate对象列表。

To sort a list of dates by year and month in ascending order and then group them, you can follow these steps:

  1. Define a custom comparator to sort the dates by year and month.
  2. Sort the list using the custom comparator.
  3. Group the sorted dates by year and month.

Here's a Java example demonstrating this approach:

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        // Sample list of dates
        List<LocalDate> dates = new ArrayList<>();
        dates.add(LocalDate.of(2022, 4, 15));
        dates.add(LocalDate.of(2021, 11, 25));
        dates.add(LocalDate.of(2023, 2, 10));
        dates.add(LocalDate.of(2022, 6, 5));
        dates.add(LocalDate.of(2021, 10, 10));
        dates.add(LocalDate.of(2022, 4, 1));
        
        // Sort the dates by year and month
        Comparator<LocalDate> comparator = Comparator.comparing(LocalDate::getYear)
                .thenComparing(LocalDate::getMonth);
        List<LocalDate> sortedDates = dates.stream()
                .sorted(comparator)
                .collect(Collectors.toList());
        
        // Group the sorted dates by year and month
        Map<String, List<LocalDate>> groupedDates = new HashMap<>();
        for (LocalDate date : sortedDates) {
            String yearMonth = date.getYear() + "-" + date.getMonthValue();
            groupedDates.computeIfAbsent(yearMonth, k -> new ArrayList<>()).add(date);
        }
        
        // Print the grouped dates
        groupedDates.forEach((key, value) -> {
            System.out.println(key + ": " + value);
        });
    }
}

This code will output the sorted dates grouped by year and month:

2021-10: [2021-10-10]
2021-11: [2021-11-25]
2022-4: [2022-04-01, 2022-04-15]
2022-6: [2022-06-05]
2023-2: [2023-02-10]

This approach first sorts the dates using a custom comparator based on the year and month. Then, it groups the sorted dates by concatenating the year and month into a string key for each group. Finally, it prints the grouped dates.

# =============================== # 第二部分:按月评估预测精度 # =============================== best_model_name = comparison_df.index[0] best_model_predictions = predictions[best_model_name] # 使用最终集成模型的测试集预测结果 pred_test = best_model_predictions # 统一变量名用于后续分析 y_test = y_test_original # 创建DataFrame df_test = pd.DataFrame({ 'dates_test': last_dates, 'y_test': last_true, 'pred_test': last_pred }) # 提取月份和年份 df_test['month'] = df_test['dates_test'].dt.month df_test['year'] = df_test['dates_test'].dt.year # 初始化评估列表 evaluation = [] # 遍历每个月份 months = sorted(df_test['month'].unique()) for month in months: month_data = df_test[df_test['month'] == month] for year in sorted(month_data['year'].unique()): specific_month_data = month_data[month_data['year'] == year] if specific_month_data.empty: continue total_days = len(specific_month_data) accurate_count = 0 overestimate_count = 0 underestimate_count = 0 # 逐日评估 for _, row in specific_month_data.iterrows(): lower_bound = row['pred_test'] * 0.75 upper_bound = row['pred_test'] * 1.25 actual_value = row['y_test'] if lower_bound <= actual_value <= upper_bound: accurate_count += 1 elif actual_value < lower_bound: overestimate_count += 1 elif actual_value > upper_bound: underestimate_count += 1 # 计算比率 accuracy_rate = accurate_count / total_days overestimate_rate = overestimate_count / total_days underestimate_rate = underestimate_count / total_days # 存储结果 evaluation.append({ 'Year': year, 'Month': month, 'Accuracy Rate': accuracy_rate, 'Overestimate Rate': overestimate_rate, 'Underestimate Rate': underestimate_rate }) # 转换为 DataFrame 并输出 evaluation_df = pd.DataFrame(evaluation) # 筛选 2024年9月 到 2025年9月 的数据 # 注意:使用字符串比较或日期逻辑确保正确范围 plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans'] plt.rcParams['font.family'] = 'sans-serif' plt.rcParams['axes.unicode_minus'] = False # 确保 YearMonth 为整数类型 evaluation_df['Year'] = evaluation_df['Year'].astype(int) evaluation_df['Month'] = evaluation_df['Month'].astype(int) # 创建 'YearMonth' 字符串用于筛选和排序 evaluation_df['YearMonth'] = evaluation_df['Year'].astype(str) + '-' + evaluation_df['Month'].astype(str).str.zfill(2) # 转换为 datetime 类型以便范围筛选 evaluation_df['Date'] = pd.to_datetime(evaluation_df['YearMonth']) # 设定起止时间:2024-09 至 2025-09 start_date = '2024-09' end_date = '2025-09' # 筛选指定时间段 mask = (evaluation_df['Date'] >= start_date) & (evaluation_df['Date'] <= end_date) filtered_df = evaluation_df[mask].copy() # 按时间排序 filtered_df.sort_values('Date', inplace=True) filtered_df.reset_index(drop=True, inplace=True) # 如果没有数据,提示错误(可选) if filtered_df.empty: print("⚠️ 在 2024年9月 至 2025年9月 范围内未找到数据。") else: import matplotlib.pyplot as plt import matplotlib.ticker as mtick import numpy as np # 准备绘图 plt.figure(figsize=(18, 7)) ind = np.arange(len(filtered_df)) width = 0.3 # 柱子宽度 # 绘制三类柱状图 accuracy_bar = plt.bar(ind - width, filtered_df['Accuracy Rate'], width, color='green', label='范围预测准确率') underestimate_bar = plt.bar(ind, filtered_df['Underestimate Rate'], width, color='red', label='范围预测低估率') overestimate_bar = plt.bar(ind + width, filtered_df['Overestimate Rate'], width, color='blue', label='范围预测高估率') # 添加数值标签 for bars in [accuracy_bar, underestimate_bar, overestimate_bar]: for bar in bars: height = bar.get_height() plt.text(bar.get_x() + bar.get_width() / 2.0, height + 0.01, f'{height:.1%}', ha='center', va='bottom', fontsize=9) # 折线图:准确率趋势 plt.plot(ind - width, filtered_df['Accuracy Rate'], marker='o', linestyle='-', color='green', label='预测准确率趋势', linewidth=2, markersize=5) # 设置标题和坐标轴 plt.title('AQI 范围预测准确率', fontsize=16) plt.xlabel('时间', fontsize=12) plt.ylabel('百分比', fontsize=12) # x轴显示 YearMonth,旋转标签 plt.xticks(ind, filtered_df['YearMonth'], rotation=45) # y轴格式化为百分数 plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1.0)) # 图例置于右侧外部 plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0) # 自动调整布局 plt.tight_layout() # 显示图形 plt.show() 将其改为折线图
11-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值