如何匹配多个DataFrame中RMS列的序列(容差范围±5)
问题描述
我有一个包含多个DataFrame的列表,每个DataFrame都有名为RMS的列。现在需要找出两个及以上的DataFrame,要求它们的RMS序列中每一个对应位置的值都处于±5的容差范围内。
举个例子:
DataFrame 1的RMS序列:
| RMS |
|---|
| 55.6 |
| 70.9 |
| 91 |
| 36 |
符合要求的匹配是DataFrame 2,它的每个RMS值都在DataFrame 1对应值的±5范围内:
| RMS(允许范围) |
|---|
| 60.6 ~ 51.6 |
| 75.9 ~ 65.9 |
| 95 ~ 85 |
| 41 ~ 31 |
我当前编写的代码只能匹配单个RMS值,无法实现序列整体匹配的需求,求正确的实现方案。
现有代码
def find_matches(df_list, tolerance=5): matches = [] for i, df1 in enumerate(df_list): for j, df2 in enumerate(df_list): if i != j: for rms_value in df1['RMS']: matched_values = df2[(df2['RMS'] >= rms_value - tolerance) & (df2['RMS'] <= rms_value + tolerance)] if not matched_values.empty: matches.append((f'dataframe-{i+1}', rms_value, f'dataframe-{j+1}', matched_values['RMS'].tolist())) return matches # 查找匹配 matches = find_matches(name_of_list_containing_data_frames, tolerance=5)
问题分析
现有代码的核心问题是只做了单个RMS值的跨DataFrame匹配,没有考虑序列的对应位置一致性:它会把DataFrame A中某个位置的RMS值,和DataFrame B中任意位置的符合容差的值配对,完全忽略了“序列整体对应”的要求。
解决方案
要实现序列整体匹配,需要先保证两个DataFrame的RMS列长度一致,再逐位置验证所有值都符合容差,同时避免重复配对(比如已记录DataFrame1和DataFrame2,就不再记录DataFrame2和DataFrame1)。
实现代码
def find_matching_dataframes(df_list, tolerance=5): matched_groups = [] # 遍历所有两两组合,i < j 避免重复配对 for i in range(len(df_list)): df1 = df_list[i] df1_name = f'dataframe-{i+1}' for j in range(i + 1, len(df_list)): df2 = df_list[j] df2_name = f'dataframe-{j+1}' # 先检查两个DataFrame的RMS列长度是否一致 if len(df1['RMS']) != len(df2['RMS']): continue # 验证所有对应位置的RMS值都在容差范围内 all_valid = ((df1['RMS'] - df2['RMS']).abs() <= tolerance).all() if all_valid: matched_groups.append({ 'pair': (df1_name, df2_name), 'df1_rms': df1['RMS'].tolist(), 'df2_rms': df2['RMS'].tolist(), 'tolerance': tolerance }) # 若需要找出多组互相匹配的DataFrame(比如3个及以上两两都符合条件),可在此基础上扩展聚类逻辑 return matched_groups # 使用示例 matches = find_matching_dataframes(name_of_list_containing_data_frames, tolerance=5) # 输出结果 for idx, match in enumerate(matches, 1): print(f"匹配组 {idx}:") print(f"配对DataFrame: {match['pair'][0]} 和 {match['pair'][1]}") print(f"{match['pair'][0]} RMS序列: {match['df1_rms']}") print(f"{match['pair'][1]} RMS序列: {match['df2_rms']}") print("---")
代码说明
- 避免重复配对:用
i < j的循环逻辑,确保每对DataFrame只被检查一次 - 长度校验:先判断两个DataFrame的RMS列长度是否一致,长度不同直接跳过
- 向量化验证:利用Pandas的向量运算一次性计算所有位置的差值绝对值,再用
.all()判断是否全部符合容差要求,效率远高于逐行遍历 - 结果清晰:返回配对信息和对应RMS序列,方便后续验证和使用
内容的提问来源于stack exchange,提问作者Abboud
相关产品推荐
相关产品推荐

