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

Python中如何将Dekad(旬)转换为起止日期并添加至DataFrame

解决方案

核心思路

Dekad(10天周期)的规则是每月3个周期:第1个周期为当月1-10日,第2个为11-20日,第3个为21日至当月月末。我们可以通过数学计算推导月份和周期段,结合pandas的日期处理能力自动生成起止日期,完全避免硬编码。

方法一:高效矢量化实现(推荐)

适合大数据量场景,无需循环或apply,性能更优:

import pandas as pd

# 示例DataFrame
df = pd.DataFrame({
    'CEI': [160.004352, 0.0, 0.0, 0.0, 0.0],
    'Dekad': [1, 2, 3, 4, 5]
})

# 1. 计算每个Dekad所属的月份和当月内的周期序号
df['month'] = (df['Dekad'] - 1) // 3 + 1
df['dekad_segment'] = (df['Dekad'] - 1) % 3 + 1

# 2. 生成起始日
df['start_day'] = df['dekad_segment'].map({1: 1, 2: 11, 3: 21})

# 3. 生成结束日:前两个周期固定为10/20日,第三个周期取当月月末
df['end_day'] = df['dekad_segment'].map({1: 10, 2: 20})
# 针对第三个周期,获取对应月份的总天数作为结束日
mask = df['dekad_segment'] == 3
df.loc[mask, 'end_day'] = pd.to_datetime(df.loc[mask, 'month'], format='%m').dt.days_in_month

# 4. 构造起止日期并拼接成目标字符串(这里默认年份为2023,可按需修改)
target_year = 2023
df['start_date'] = pd.to_datetime(f"{target_year}-" + df['month'].astype(str) + "-" + df['start_day'].astype(str))
df['end_date'] = pd.to_datetime(f"{target_year}-" + df['month'].astype(str) + "-" + df['end_day'].astype(str))
df['date_range_dekad'] = df['start_date'].dt.strftime('%Y-%m-%d') + ' 至 ' + df['end_date'].dt.strftime('%Y-%m-%d')

# 清理中间辅助列
df.drop(['month', 'dekad_segment', 'start_day', 'end_day', 'start_date', 'end_date'], axis=1, inplace=True)

print(df)

执行后输出结果:

CEI  Dekad       date_range_dekad
0  160.004352      1  2023-01-01 至 2023-01-10
1    0.000000      2  2023-01-11 至 2023-01-20
2    0.000000      3  2023-01-21 至 2023-01-31
3    0.000000      4  2023-02-01 至 2023-02-10
4    0.000000      5  2023-02-11 至 2023-02-20

方法二:自定义函数+apply实现(适合小数据量/逻辑更直观)

如果数据量不大,用apply结合自定义函数更易理解和调试:

import pandas as pd
from datetime import datetime, timedelta

def get_dekad_range(dekad_num, year=2023):
    # 计算所属月份
    month = (dekad_num - 1) // 3 + 1
    # 计算当月内的周期序号
    segment = (dekad_num - 1) % 3 + 1
    
    if segment == 1:
        start, end = 1, 10
    elif segment == 2:
        start, end = 11, 20
    else:
        # 获取当月最后一天
        last_day = datetime(year, month, 1) + pd.DateOffset(months=1) - timedelta(days=1)
        start, end = 21, last_day.day
    
    start_date = datetime(year, month, start).strftime('%Y-%m-%d')
    end_date = datetime(year, month, end).strftime('%Y-%m-%d')
    return f"{start_date} 至 {end_date}"

# 应用到DataFrame
df['date_range_dekad'] = df['Dekad'].apply(get_dekad_range)

关键说明

  • 年份可按需修改:上述代码默认使用2023年,若需要动态年份,可将年份作为参数传入,或从DataFrame的其他列读取。
  • 月末自动适配:通过pd.to_datetime(...).dt.days_in_month或日期偏移计算,自动处理不同月份的天数差异(如2月的28/29天、31天的大月等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:36:14