如何对比pandas DataFrame的数值与顺序,并判断其中一个是否为另一个的子集
时间序列DataFrame有序子集校验方案
校验逻辑说明
你需要的三重校验规则可以拆解为以下3个必满足条件:
- 子DataFrame的所有列名均存在于父DataFrame中
- 子DataFrame的所有单元格数值,与父DataFrame中对应匹配段的数值完全一致
- 子DataFrame的行排列顺序,与父DataFrame中匹配段的行顺序完全相同,不允许乱序匹配
实现代码
方案1:时间索引场景(推荐,适配时间序列特性)
时间序列默认以时间戳为索引,天然携带顺序属性,该方案校验效率更高,同时覆盖索引顺序、数值、存在性校验:
import pandas as pd def is_timeseries_subset(df_sub: pd.DataFrame, df_parent: pd.DataFrame) -> bool: # 校验列是否全部存在 if not set(df_sub.columns).issubset(set(df_parent.columns)): return False # 校验子表时间索引全部存在于父表 if not set(df_sub.index).issubset(set(df_parent.index)): return False # 按子表索引顺序取父表对应数据,逐值对比 parent_slice = df_parent.loc[df_sub.index, df_sub.columns] return df_sub.equals(parent_slice)
方案2:无时间索引通用场景
如果未使用时间作为索引,仅需要校验行顺序与数值匹配,可使用滚动窗口逐段匹配:
def is_ordered_row_subset(df_sub: pd.DataFrame, df_parent: pd.DataFrame) -> bool: sub_len = len(df_sub) parent_len = len(df_parent) # 子表长度大于父表直接返回否 if sub_len > parent_len: return False # 校验列是否全部存在 if not set(df_sub.columns).issubset(set(df_parent.columns)): return False # 提取公共列做对比 parent_common = df_parent[df_sub.columns] # 滚动窗口匹配所有连续子段 for start_idx in range(parent_len - sub_len + 1): if parent_common.iloc[start_idx:start_idx+sub_len].equals(df_sub): return True return False
附加技巧
如果校验不通过需要定位差异位置,可使用df_sub.compare(parent_slice)直接输出不匹配的单元格位置与两边的数值。
内容的提问来源于stack exchange,提问作者haeny
相关产品推荐
相关产品推荐

