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

在DataFrame中查找最近时间:两种时间格式数据集匹配需求

嘿,这个问题我熟,咱们一步步来搞定它!核心思路就是先把两个数据集的时间统一成pandas能识别的datetime格式,再计算每个时间点的最近匹配项。

具体实现步骤

1. 统一时间格式

首先得把两种不同的时间格式转换成标准的datetime类型:

  • df1里的A列是Unix秒级时间戳,用pd.to_datetime()时指定unit='s'就能解析;
  • df2里的B列是ISO 8601格式的字符串,直接用pd.to_datetime()就能自动识别。
import pandas as pd

# 你的原始数据
df1 = pd.DataFrame( {'A': [1499503900, 1512522054, 1412525061, 1502527681, 1512532303]})
df2 = pd.DataFrame( {'B' : ['2017-12-15T11:47:58.119Z', '2017-05-31T08:27:41.943Z', '2017-06-05T14:44:56.425Z', '2017-05-30T16:24:03.175Z' , '2017-07-03T10:20:46.333Z', '2017-06-16T10:13:31.535Z' , '2017-12-15T12:26:01.347Z', '2017-06-15T16:00:41.017Z', '2017-11-28T15:25:39.016Z', '2017-08-10T08:48:01.347Z'] })

# 转换时间格式
df1['A_datetime'] = pd.to_datetime(df1['A'], unit='s')
df2['B_datetime'] = pd.to_datetime(df2['B'])

2. 匹配最近的时间

接下来为df1的每一行,在df2中找到时间差最小的记录。这里有两种方法,适合不同规模的数据集:

方法一:适合小规模数据集(简单直观)

用apply()遍历df1的每一行,计算当前时间与df2所有时间的绝对差,然后取差值最小的那一项:

def get_closest_time(row):
    # 计算当前时间和df2所有时间的绝对差值
    time_diffs = abs(df2['B_datetime'] - row['A_datetime'])
    # 找到差值最小的索引
    closest_idx = time_diffs.idxmin()
    # 返回对应的原始时间字符串和转换后的datetime
    return pd.Series(
        [df2.loc[closest_idx, 'B'], df2.loc[closest_idx, 'B_datetime']],
        index=['closest_B', 'closest_B_datetime']
    )

# 把匹配结果合并到df1中
df1 = pd.concat([df1, df1.apply(get_closest_time, axis=1)], axis=1)

方法二:适合大规模数据集(高效优化)

如果你的数据量很大,上面的方法会因为每次遍历整个df2而变慢。可以先对df2的时间排序,然后用二分查找快速定位最近的时间,效率会提升很多:

# 先对df2按时间排序
df2_sorted = df2.sort_values('B_datetime').reset_index(drop=True)
sorted_times = df2_sorted['B_datetime']

def get_closest_time_fast(row):
    current_time = row['A_datetime']
    # 用二分查找找到插入位置
    pos = sorted_times.searchsorted(current_time)
    
    # 处理边界情况:如果是第一个时间点,直接取第一个;如果是最后一个,取最后一个
    if pos == 0:
        closest_idx = 0
    elif pos == len(sorted_times):
        closest_idx = len(sorted_times) - 1
    else:
        # 比较前后两个时间的差值,选更近的那个
        time_before = sorted_times.iloc[pos-1]
        time_after = sorted_times.iloc[pos]
        if (current_time - time_before) < (time_after - current_time):
            closest_idx = pos - 1
        else:
            closest_idx = pos
    
    return pd.Series(
        [df2_sorted.loc[closest_idx, 'B'], sorted_times.iloc[closest_idx]],
        index=['closest_B', 'closest_B_datetime']
    )

# 合并结果到df1
df1 = pd.concat([df1, df1.apply(get_closest_time_fast, axis=1)], axis=1)

最终效果

运行后,df1会新增两列:

  • closest_B:df2中匹配到的原始时间字符串;
  • closest_B_datetime:对应的datetime格式时间。

比如df1里第一个时间戳1499503900转换后是2017-07-08 05:31:40,匹配到的最近时间就是df2里的2017-07-03T10:20:46.333Z。

内容的提问来源于stack exchange,提问作者emily.mi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:10:05