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

如何通过Pandas DataFrame映射生成新列:匹配时间获日期与温度

Pandas时间范围匹配:从Lookup表映射日期与温度

现有两个Pandas DataFrame:

import pandas as pd

df1 = pd.DataFrame({
    'temperature': ['cold', 'warm', 'hot'],
    'Mon_start': ['1:00', '7:00', '4:00'],
    'Mon_end': ['3:00', '8:00', '6:00'],
    'Tues_start': ['9:00', '16:00', '12:00'],
    'Tues_end': ['10:00', '20:00', '14:00']
})

df2 = pd.DataFrame({
    'sample1': ['A', 'A', 'B', 'B'],
    'data_value': ['2:00', '7:30', '18:00', '9:45']
})

需求:以df1为查找表,检查df2的data_value是否落在某一日期的起止时间范围内,匹配后为df2新增day(对应日期)和temperature(对应温度)列,期望输出:

sample1 data_value   day temperature
0       A       2:00   Mon        cold
1       A       7:30   Mon        warm
2       B      18:00  Tues        warm
3       B       9:45  Tues        cold

由于数据量较大,避免低效循环,以下是高效实现方案:


步骤1:转换时间格式为可比较的时间差类型

将所有时间字符串转换为timedelta类型,方便后续范围判断:

# 转换df1的时间列
time_cols = [col for col in df1.columns if '_start' in col or '_end' in col]
df1[time_cols] = df1[time_cols].apply(pd.to_timedelta)

# 转换df2的data_value
df2['data_value'] = pd.to_timedelta(df2['data_value'])

步骤2:重塑df1为长格式(宽表转窄表)

把每个日期的起止时间与温度对应,形成一行一个匹配规则的结构:

# 拆分Mon和Tues的规则
mon_df = df1[['temperature', 'Mon_start', 'Mon_end']].rename(
    columns={'Mon_start': 'start', 'Mon_end': 'end'}
).assign(day='Mon')

tues_df = df1[['temperature', 'Tues_start', 'Tues_end']].rename(
    columns={'Tues_start': 'start', 'Tues_end': 'end'}
).assign(day='Tues')

# 合并为规则表
rules_df = pd.concat([mon_df, tues_df], ignore_index=True)

此时rules_df的结构为:

temperaturestartendday
cold01:00:0003:00:00Mon
warm07:00:0008:00:00Mon
hot04:00:0006:00:00Mon
cold09:00:0010:00:00Tues
warm16:00:0020:00:00Tues
hot12:00:0014:00:00Tues

步骤3:高效匹配时间范围

利用IntervalIndex快速判断每个data_value属于哪个时间区间,再关联对应的day和temperature:

# 创建时间区间索引
intervals = pd.IntervalIndex.from_arrays(rules_df['start'], rules_df['end'], closed='both')

# 找到每个data_value对应的区间索引
match_idx = df2['data_value'].apply(lambda x: intervals.get_loc(x))

# 关联规则表的结果
result = df2.join(rules_df.loc[match_idx, ['day', 'temperature']].reset_index(drop=True))

执行后result就是期望的输出。

为什么不用循环或np.vectorize?

  • 循环遍历会导致时间复杂度随数据量线性增长,数据量大时效率极低。
  • np.vectorize本质上还是循环,并没有真正实现向量化加速,只是语法上更简洁。
  • 上述方案利用Pandas的内置数据结构(IntervalIndex)和向量化操作,效率远高于循环,适合处理大规模数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:55:20