R中统计dataframe连续TRUE/FALSE长度并过滤超长连续NA序列
连续序列统计与ID过滤实现方案
核心思路
- 先对数据按
id、date、time升序排序,确保每个id的记录按时间先后排列,连续序列的统计才有意义 - 给每个id下的连续NA/非NA段生成唯一分组标记,同一段的所有行标记相同
- 按分组统计段总长度,回填到同一段的所有行
- 基于统计的NA段长度过滤不符合要求的id
R实现(适配你提到的rle逻辑)
你之前用rle只得到递增计数的原因是没有将rle返回的段长度回填到对应段的所有行,用rep()重复对应长度即可解决:
library(dplyr) # 1. 按时间排序 df <- df %>% arrange(id, date, time) # 2. 新增连续段总长度列(两种写法可选) # 写法1:rle原生方案 df <- df %>% group_by(id) %>% mutate(seg_total_len = with(rle(gap), rep(lengths, lengths))) %>% ungroup() # 写法2:cumsum分组方案,逻辑更直观 # df <- df %>% # group_by(id) %>% # mutate(seg_id = cumsum(c(TRUE, diff(gap) != 0))) %>% # group_by(id, seg_id) %>% # mutate(seg_total_len = n()) %>% # ungroup() %>% # select(-seg_id) # 3. 过滤id:删除存在连续NA长度≥5的id,剩余id全部保留 valid_ids <- df %>% group_by(id, gap) %>% summarise(max_seg_len = max(seg_total_len), .groups = "drop") %>% filter(!(gap == TRUE & max_seg_len >= 5)) %>% # 若你的gap列TRUE代表非NA,这里改为gap == FALSE distinct(id) %>% pull(id) result_df <- df %>% filter(id %in% valid_ids)
Python Pandas实现
import pandas as pd # 1. 按时间排序 df = df.sort_values(by=['id', 'date', 'time']).reset_index(drop=True) # 2. 新增连续段总长度列 df['seg_id'] = df.groupby('id')['gap'].transform(lambda x: (x != x.shift()).cumsum()) df['seg_total_len'] = df.groupby(['id', 'seg_id'])['id'].transform('count') df = df.drop(columns=['seg_id']) # 3. 过滤id invalid_ids = df[(df['gap'] == True)].groupby('id')['seg_total_len'].max() # gap定义和R侧保持一致 invalid_ids = invalid_ids[invalid_ids >=5].index.tolist() result_df = df[~df['id'].isin(invalid_ids)]
注意:请根据你自己gap列的定义调整过滤逻辑的布尔值,如果你的gap列标记为TRUE代表lat非NA,把过滤条件里的gap == TRUE改为gap == FALSE即可。
内容的提问来源于stack exchange,提问作者cgxytf
相关产品推荐
相关产品推荐

