如何用Pandas按Unique id分组检查Indicator列是否匹配指定序列
解决方案:检查分组后的序列匹配问题
问题分析
你尝试的df.groupby(['Unique id'])['Indicator'].isin([1,1,1])无法运行,原因有两点:
groupby返回的是SeriesGroupBy对象,没有isin方法;- 即使能调用
isin,它的作用是检查单个元素是否在集合中,无法识别连续的序列匹配。
解决代码
步骤1:构造示例数据
import pandas as pd data = { 'Date': [2018, 2019, 2020, 2020, 2018, 2019, 2020, 2021], 'Unique id': [1, 1, 1, 2, 2, 2, 2, 2], 'Indicator': [1, 0, 0, 1, 0, 1, 1, 1] } df = pd.DataFrame(data)
步骤2:定义序列检查函数
编写自定义函数,判断分组后的Indicator序列是否包含目标连续序列:
def has_target_sequence(series, target_seq): seq_length = len(target_seq) # 遍历所有可能的起始位置,检查子序列是否匹配 for i in range(len(series) - seq_length + 1): if list(series.iloc[i:i+seq_length]) == target_seq: return True return False
步骤3:分组应用函数并生成结果
target = [1, 1, 1] result = df.groupby('Unique id')['Indicator'].apply(has_target_sequence, target_seq=target).reset_index(name='Sequence match')
输出结果
运行后得到的result即为你需要的表格:
| Unique id | Sequence match |
|---|---|
| 1 | False |
| 2 | True |
高效优化方案(滚动窗口版)
如果数据量较大,可使用滚动窗口提升效率:
def has_target_sequence_rolling(series, target_seq): seq_length = len(target_seq) if len(series) < seq_length: return False # 将窗口内的元素转为元组,与目标元组对比 window_matches = series.rolling(seq_length).apply( lambda x: tuple(x) == tuple(target_seq), raw=True ) return window_matches.any() result = df.groupby('Unique id')['Indicator'].apply(has_target_sequence_rolling, target_seq=target).reset_index(name='Sequence match')
内容的提问来源于stack exchange,提问作者Nauan Sarbasov
相关产品推荐
相关产品推荐

