按日期分组:val列出现连续两个y后当日剩余行标记True
问题:按日分组标记连续双"y"后的行
给定如下DataFrame,需新增一列out,规则为:
- 按自然日分组,每日逻辑独立重置
- 当某组内
val列出现连续两个"y"时,将该组中这两个"y"之后的所有行标记为True,其余行标记为False
示例数据
import pandas as pd df_so = pd.DataFrame( { "val": list("yynnnyyynn") }, index=pd.date_range(start="1/1/2018", periods=10, freq="6h"), )
数据展示:
val 2018-01-01 00:00:00 y 2018-01-01 06:00:00 y 2018-01-01 12:00:00 n 2018-01-01 18:00:00 n 2018-01-02 00:00:00 n 2018-01-02 06:00:00 y 2018-01-02 12:00:00 y 2018-01-02 18:00:00 y 2018-01-03 00:00:00 n 2018-01-03 06:00:00 n
期望输出
val out 2018-01-01 00:00:00 y False 2018-01-01 06:00:00 y False 2018-01-01 12:00:00 n True 2018-01-01 18:00:00 n True 2018-01-02 00:00:00 n False 2018-01-02 06:00:00 y False 2018-01-02 12:00:00 y False 2018-01-02 18:00:00 y True 2018-01-03 00:00:00 n False 2018-01-03 06:00:00 n False
解决方案
实现思路
按自然日分组后,在每组内完成以下操作:
- 标记出当前行与下一行均为"y"的位置
- 找到该组中第一个连续双"y"的位置,将其下一行设为标记True的起始点
- 对起始点之后的所有行标记True,其余行标记False
代码实现
def mark_post_consecutive_y(group): # 标记连续两个"y"的位置(当前行和下一行都是y) consecutive_y = (group['val'] == 'y') & (group['val'].shift(-1) == 'y') if consecutive_y.any(): # 获取第一个连续双y的索引,取其下一个位置作为标记起点 first_consec_idx = consecutive_y.idxmax() start_pos = group.index.get_loc(first_consec_idx) + 1 # 初始化out列为False,再将起点后的行设为True group['out'] = False if start_pos < len(group): group.loc[group.index[start_pos:], 'out'] = True else: # 无连续双y时全为False group['out'] = False return group # 按日期分组应用逻辑 df_result = df_so.groupby(df_so.index.date).apply(mark_post_consecutive_y) print(df_result)
关键说明
groupby(df_so.index.date)确保每日逻辑独立,不会跨日期影响consecutive_y通过移位操作快速定位连续双"y"的位置- 仅对第一个出现连续双"y"的位置之后的行标记True,符合需求中的"该日后续所有行"规则
内容的提问来源于stack exchange,提问作者nipy
相关产品推荐
相关产品推荐

