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

如何在DataFrame重采样周期中获取极值及其对应发生日期?

问题描述

我有一个以datetime为索引、仅包含资产价格列的DataFrame,示例如下:

asset_value
date                 
2023-05-30   136.57000000
2023-05-31   133.30000000
2023-06-01   134.83000000
2023-06-02   134.63000000
2023-06-05   133.73000000

数据跨度数年,我希望按不同周期(比如周)对DataFrame重采样,计算周期内的min()和max()值,用以下代码可以实现:

df.resample("W").agg({'asset_value': ["min", "max"]})

返回结果如下:

asset_value           
                    min        max
date                              
2023-06-04    133.300000  136.570000
2023-06-11    133.730000  136.200000
2023-06-18    138.930000  141.790000
2023-06-25    136.070000  138.920000
2023-07-02    139.800000  146.550000

但这个结果只返回了区间极值和区间右边界日期,我还想知道这些极值对应的具体发生日期。

我尝试过在原DataFrame中添加额外列(星期几、日、月、年),但没成功,代码如下:

# 确保索引是datetime类型
df.index = pd.to_datetime(df.index)
df.reset_index(inplace=True)

# 添加星期几、日、月、年列
df['day_of_week'] = df['date'].dt.dayofweek
df['day_of_month'] = df['date'].dt.day
df['month'] = df['date'].dt.month
df['year'] = df['date'].dt.year

# 重新设置datetime索引并删除date列
df.set_index(df['date'], inplace=True)
df.drop(['date'], axis=1, inplace=True)
解决方案

要获取极值对应的日期,直接利用pandas的idxmin和idxmax方法即可,这两个方法会返回极值对应的原索引(即日期),无需额外添加日期列。

方法1:直接扩展聚合函数列表

修改重采样的agg参数,同时计算极值和对应的日期,之后再整理列名让结果更直观:

# 确保索引是datetime类型(若未处理)
df.index = pd.to_datetime(df.index)

# 按周重采样,同时计算极值及对应日期
result = df.resample("W").agg({
    'asset_value': ['min', 'max', 'idxmin', 'idxmax']
})

# 扁平化多级列名
result.columns = ['min_value', 'max_value', 'min_date', 'max_date']
# 可选:将重采样的区间日期转为普通列
result.reset_index(inplace=True)

执行后会得到类似这样的结果:

date  min_value  max_value   min_date   max_date
0 2023-06-04    133.300    136.570 2023-05-31 2023-05-30
1 2023-06-11    133.730    136.200 2023-06-05 2023-06-XX
...

方法2:自定义聚合函数(处理特殊场景)

如果需要处理极值重复的情况(比如同一个周期内多次出现相同极值),可以自定义聚合函数来获取所有极值日期:

def get_min_info(series):
    min_val = series.min()
    # 获取所有出现最小值的日期,转为逗号分隔的字符串
    min_dates = ','.join(series[series == min_val].index.strftime('%Y-%m-%d'))
    return pd.Series([min_val, min_dates], index=['min_value', 'min_dates'])

def get_max_info(series):
    max_val = series.max()
    max_dates = ','.join(series[series == max_val].index.strftime('%Y-%m-%d'))
    return pd.Series([max_val, max_dates], index=['max_value', 'max_dates'])

# 按周重采样
result = df.resample("W").agg({
    'asset_value': [get_min_info, get_max_info]
})

# 扁平化多级列名
result.columns = result.columns.map('_'.join)
result.reset_index(inplace=True)

这种方式可以返回周期内所有出现极值的日期,适合需要完整记录极值出现时间的场景。

注意事项

  • idxmin和idxmax默认返回第一个出现极值的日期,若需要所有极值日期,参考方法2的自定义函数逻辑即可。
  • 确保原DataFrame的索引是datetime类型,否则idxmin/idxmax无法返回正确的日期信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 12:43:20