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

如何结合Pandas resample与nsmallest按日期提取各列第二小值?

如何结合resample与nsmallest提取每日第二小值

嘿,这个需求我熟,咱们一步步来搞定它!首先先把你的示例数据转换成可操作的DataFrame,方便后续演示:

import pandas as pd

# 构造你的示例数据
data = [
    ["2020-01-07 09:00:00",22,228],
    ["2020-01-07 10:00:00",22,228],
    ["2020-01-07 11:00:00",22,228],
    ["2020-01-07 12:00:00",22,228],
    ["2020-01-07 13:00:00",22,228],
    ["2020-01-07 14:00:00",22,228],
    ["2020-01-07 15:00:00",21,228],
    ["2020-01-07 16:00:00",22,228],
    ["2020-01-08 09:00:00",43,45],
    ["2020-01-08 10:00:00",44,45],
    ["2020-01-08 11:00:00",41,45],
    ["2020-01-08 12:00:00",47,43]
]

df = pd.DataFrame(data, columns=["DateTime", "Col1", "Col2"])
df["DateTime"] = pd.to_datetime(df["DateTime"])

核心思路是按日期分组(resample)后,对每个分组的每一列提取第2小的值,这里有两种简洁的实现方式:

方法一:resample + apply 链式处理

我们可以对resample后的每个组,直接用apply调用nsmallest(2)取前2小值,再取最后一个(也就是第二小的,因为nsmallest会按升序排列):

# 按天重采样,提取每列第二小值
second_smallest = df.resample('D', on='DateTime').apply(lambda x: x.nsmallest(2).iloc[-1])
print(second_smallest)

代码解释

  • resample('D', on='DateTime'):按自然天对数据分组,指定DateTime列为时间依据
  • lambda x: x.nsmallest(2).iloc[-1]:对每个分组的每一列,先筛选出前2小的行,再取最后一行。如果某列当天所有值都相同,nsmallest(2)会返回两个重复值,取最后一个还是同一个值,完全符合预期。

方法二:resample + agg 自定义函数(可读性更强)

如果需要处理边界情况(比如某天只有1条数据),可以写个自定义函数,用agg方法统一处理:

def get_second_smallest(series):
    # 处理边界:如果当天数据不足2条,返回唯一值;否则返回第二小值
    return series.nsmallest(2).iloc[-1] if len(series) >= 2 else series.iloc[0]

second_smallest = df.resample('D', on='DateTime').agg(get_second_smallest)
print(second_smallest)

输出结果

两种方法都会得到如下结果:

Col1  Col2
DateTime              
2020-01-07    22   228
2020-01-08    43    45

验证一下:

  • 2020-01-07的Col1最小值是21,第二小是22;Col2全为228,所以第二小也是228
  • 2020-01-08的Col1排序后是41、43,第二小是43;Col2排序后是43、45,第二小是45,完全符合你的需求!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:19:07