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

如何遍历指定时间区间组合,获取两种方法的最小角度差值?

问题描述

我用Python实现了两种基于Pandas DataFrame数据的向量计算方法,现在需要在指定时间约束内遍历所有可能的两个时间区间组合,找到能让两种方法结果角度差最小的区间组合。

数据背景

数据格式示例:

epoch                r1         r2      r3
2020-07-07T08:17    -6.366163  11.8    -1.2
2020-07-07T08:18    -5.163     10.38   -2.5
2020-07-07T08:19    -4.3        9.4     5.2
...........
2020-07-07T14:00    1.25        22.2    1.5

现有代码流程:

  1. 时间处理:将epoch转为datetime格式,提取时间字符串用于区间筛选
  2. 两种向量计算方法:
    • 方法1:基于合并区间数据的协方差矩阵特征值分解,取最小特征值对应的特征向量
    • 方法2:基于两个区间均值向量的叉积计算归一化向量
  3. 角度差计算:通过向量点积计算两个方法结果的角度差(转为度数)

核心需求

在时间约束下(比如第一个区间限制在09:00-11:00,第二个区间限制在11:00-12:00),遍历所有合法的df_1(第一个区间)和df_2(第二个区间)组合,执行完整计算流程,找到角度差最小的区间组合并输出。要求避免遗漏最优区间,角度差<1度为最优,>10度为较差。


解决方案

步骤1:优化时间处理逻辑

直接使用datetime对象处理时间,避免字符串比较的歧义,同时提取所有唯一时间点作为区间分割候选:

import pandas as pd
import numpy as np
import datetime

# 读取数据(注意:原数据中r1列的"1 0.25"需先转为1.25格式)
df = pd.read_csv("example.csv")
df['epoch'] = pd.to_datetime(df['epoch'], format='%Y-%m-%dT%H:%M')
# 提取所有唯一时间点,用于生成区间组合
time_points = sorted(df['epoch'].unique())

步骤2:封装核心计算函数

将现有计算逻辑拆分为独立函数,提高复用性和可读性:

def compute_method1(df1, df2):
    """基于协方差矩阵特征值分解计算归一化向量"""
    df_add = pd.concat([df1, df2], ignore_index=True)
    data = np.array([df_add['r1'], df_add['r2'], df_add['r3']])
    covMatrix = np.cov(data, bias=True)
    eigval_mva, eigvec_mva = np.linalg.eig(covMatrix)
    eigval_mva = eigval_mva.real
    mincol = np.argmin(eigval_mva)
    eigenvect = eigvec_mva[:, mincol].real
    return eigenvect / np.linalg.norm(eigenvect)

def compute_method2(df1, df2):
    """基于均值向量叉积计算归一化向量"""
    r1_mean = df1[['r1', 'r2', 'r3']].mean().values
    r2_mean = df2[['r1', 'r2', 'r3']].mean().values
    diff = r1_mean - r2_mean
    cross_r = np.cross(r1_mean, r2_mean)
    v = np.cross(diff, cross_r)
    norm_v = v / np.linalg.norm(v) if np.linalg.norm(v) != 0 else np.zeros(3)
    return norm_v

def calculate_angle(v1, v2):
    """计算两个归一化向量的角度差(度数)"""
    if np.all(v1 == 0) or np.all(v2 == 0):
        return np.inf  # 无效向量返回无穷大
    dot_product = np.dot(v1, v2)
    # 避免浮点精度溢出导致arccos报错
    dot_product = np.clip(dot_product, -1.0, 1.0)
    rad = np.arccos(dot_product)
    return np.rad2deg(rad)

步骤3:遍历所有合法区间组合

根据时间约束生成所有候选区间,计算并记录最优结果:

# 设定时间约束
df1_start_bound = datetime.datetime(2020, 7, 7, 9, 0)
df1_end_bound = datetime.datetime(2020, 7, 7, 11, 0)
df2_start_bound = datetime.datetime(2020, 7, 7, 11, 0)
df2_end_bound = datetime.datetime(2020, 7, 7, 12, 0)

# 筛选符合约束的时间点
df1_candidates = [t for t in time_points if df1_start_bound <= t <= df1_end_bound]
df2_candidates = [t for t in time_points if df2_start_bound <= t <= df2_end_bound]

# 初始化最优结果
min_angle = np.inf
best_intervals = None

# 遍历所有df1区间组合(start <= end)
for i in range(len(df1_candidates)):
    df1_start = df1_candidates[i]
    for j in range(i+1, len(df1_candidates)):
        df1_end = df1_candidates[j]
        df1 = df[(df['epoch'] >= df1_start) & (df['epoch'] <= df1_end)]
        if len(df1) < 2:  # 数据量不足跳过
            continue
        
        # 遍历所有df2区间组合(start <= end)
        for k in range(len(df2_candidates)):
            df2_start = df2_candidates[k]
            for l in range(k+1, len(df2_candidates)):
                df2_end = df2_candidates[l]
                df2 = df[(df['epoch'] >= df2_start) & (df['epoch'] <= df2_end)]
                if len(df2) < 2:
                    continue
                
                # 执行计算
                v1 = compute_method1(df1, df2)
                v2 = compute_method2(df1, df2)
                angle_deg = calculate_angle(v1, v2)
                
                # 更新最优结果
                if angle_deg < min_angle:
                    min_angle = angle_deg
                    best_intervals = {
                        "df1_start": df1_start.strftime("%Y-%m-%d %H:%M"),
                        "df1_end": df1_end.strftime("%Y-%m-%d %H:%M"),
                        "df2_start": df2_start.strftime("%Y-%m-%d %H:%M"),
                        "df2_end": df2_end.strftime("%Y-%m-%d %H:%M"),
                        "angle_diff": round(angle_deg, 2)
                    }

# 输出最优结果
print("最优区间组合:")
if best_intervals:
    print(f"第一个区间:{best_intervals['df1_start']} 至 {best_intervals['df1_end']}")
    print(f"第二个区间:{best_intervals['df2_start']} 至 {best_intervals['df2_end']}")
    print(f"角度差:{best_intervals['angle_diff']}°")
else:
    print("未找到有效区间组合")

关键优化说明

  1. 时间处理:用datetime对象直接比较,避免字符串格式歧义
  2. 数值稳定性:添加np.clip避免浮点精度问题导致arccos报错,处理零向量特殊情况
  3. 数据过滤:跳过数据量小于2的区间,避免协方差矩阵计算失效
  4. 遍历逻辑:严格按照时间约束生成候选区间,确保不遗漏所有合法组合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:31:06