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

基于时间的Pandas智能索引:设备状态任意日期查询实现

Pandas实现设备状态的时间点查询(支持自定义初始状态)

我来给你梳理一个优雅的Pandas实现方案,完美覆盖你提到的所有查询场景,还能灵活切换初始状态。

步骤1:数据预处理

首先我们先把原始数据转换成Pandas能高效处理的格式,核心是把Date列转为datetime类型,方便后续的时间比较和索引操作:

import pandas as pd

# 构建你的示例数据
data = {
    "Date": ["1990/01", "1990/01", "1990/03", "1990/05", "2000/01"],
    "Device": [50, 20, 25, 50, 20],
    "Status": ["ON", "ON", "ON", "OFF", "OFF"]
}
df = pd.DataFrame(data)
# 将日期转换为datetime格式,这是时间序列操作的基础
df["Date"] = pd.to_datetime(df["Date"])

步骤2:构建设备状态的时间映射表

我们需要为每个设备生成一个包含初始状态的完整时间-状态映射,这样查询时就能通过前向填充的逻辑自动延续状态。这里写一个通用函数,支持传入自定义初始状态:

def prepare_status_map(df, initial_status="OFF"):
    # 按设备分组处理,每个设备单独维护状态序列
    status_maps = {}
    for device, group in df.groupby("Device"):
        # 先按日期排序,确保状态变更的时间顺序正确
        sorted_group = group.sort_values("Date").reset_index(drop=True)
        # 生成一个比该设备最早记录早一天的虚拟行,用来定义初始状态
        earliest_date = sorted_group["Date"].min()
        initial_row = pd.DataFrame({
            "Date": [earliest_date - pd.Timedelta(days=1)],
            "Device": [device],
            "Status": [initial_status]
        })
        # 合并初始行和原始数据,再重新排序
        combined = pd.concat([initial_row, sorted_group]).sort_values("Date")
        # 将日期设为索引,方便后续快速查询
        status_maps[device] = combined.set_index("Date")["Status"]
    return status_maps

步骤3:实现查询函数

利用Pandas的索引定位能力,我们可以高效找到任意日期对应的设备状态,逻辑完全匹配你的需求:

def query_device_status(status_maps, device, query_date):
    # 统一转换查询日期为datetime格式
    query_date = pd.to_datetime(query_date)
    
    # 如果设备无任何记录,返回初始状态(取映射表中任意设备的初始值,或默认OFF)
    if device not in status_maps:
        return status_maps[next(iter(status_maps.keys()))].iloc[0] if status_maps else "OFF"
    
    device_status = status_maps[device]
    try:
        # 使用pad模式找到小于等于查询日期的最近索引,获取对应状态
        idx = device_status.index.get_loc(query_date, method="pad")
        return device_status.iloc[idx]
    except KeyError:
        # 若查询日期早于初始虚拟行的日期,直接返回初始状态
        return device_status.iloc[0]

测试所有场景

场景1:默认初始状态为OFF(你的基础需求)

# 构建初始状态为OFF的映射表
status_maps_off = prepare_status_map(df, initial_status="OFF")

# 测试各个查询场景
print(query_device_status(status_maps_off, 50, "1990/01"))  # 输出: ON(直接匹配)
print(query_device_status(status_maps_off, 50, "1990/02"))  # 输出: ON(无记录,保持上一次状态)
print(query_device_status(status_maps_off, 50, "1990/05"))  # 输出: OFF(直接匹配)
print(query_device_status(status_maps_off, 50, "2000/09"))  # 输出: OFF(最后一次变更后保持)
print(query_device_status(status_maps_off, 50, "1900/01"))  # 输出: OFF(首次记录前默认OFF)

场景2:初始状态为ON(扩展需求)

只需要在构建映射表时传入initial_status="ON"即可:

# 构建初始状态为ON的映射表
status_maps_on = prepare_status_map(df, initial_status="ON")

# 测试首次记录前的情况
print(query_device_status(status_maps_on, 50, "1900/01"))  # 输出: ON

方案优势

  • 优雅高效:利用Pandas的分组、索引和定位能力,避免了繁琐的循环遍历,性能更优
  • 灵活扩展:通过参数initial_status轻松切换两种初始状态场景
  • 鲁棒性强:处理了设备无记录、查询日期早于所有记录等边缘情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:54:29