【问题标题】:Get occurences of at least n consecutive rows meeting a specific condition?获取满足特定条件的至少 n 个连续行的出现?
【发布时间】:2021-12-14 20:12:56
【问题描述】:

我有一个带有二进制列 target, 的数据框 df,我想计算 至少 n 连续行的出现次数,使得 df[target] == 1

我找到了很多关于计算 (确切) n 在某些数据框列上满足给定条件的连续行的出现的答案。但他们并没有解决我的问题。

我可以利用目标是有限的这一事实来构建以下算法来解决我的问题:

target = [0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1]
df = pd.DataFrame(
    {"target" : target}
)
n = 3
groups = []
for i in range(df.size):
    if df["target"].iloc[i] == 0:
        continue
    group_index_min = df.index[i]
    for j in range(i, df.size):
        if df["target"].iloc[j] == 1:
            group_index_max = df.index[j]
        else:
            break
    current_group = (group_index_min, group_index_max)
    is_sub_group = False
    for group in groups:
        a, b = group
        if a <= group_index_min and group_index_max <= b:
            is_sub_group = True
    if (not is_sub_group) and (group_index_max - group_index_min + 1 >= n):
        groups.append(current_group)

groups
# >> [(2, 4), (9, 11), (31, 36)]

但是,我更喜欢使用 numpy 或 pandas 的解决方案,更 Pythonic。

有人可以帮助我吗?非常感谢!

【问题讨论】:

    标签: python-3.x pandas dataframe


    【解决方案1】:

    试试:

    get_group = lambda x: (x.index[0], x.index[-1]) if len(x) >= 3 else None
    
    groups = df['target'].eq(0).cumsum()[df['target'].ne(0)].to_frame() \
                         .groupby('target').apply(get_group).dropna().tolist()
    print(groups)
    
    # Output:
    [(2, 4), (9, 11), (31, 36)]
    

    【讨论】:

      【解决方案2】:
      # find index values where target goes from 0 to 1 or from 1 to 0
      change_points = df[(df.target == 1) & ((df.target.shift(fill_value=0) == 0) | (df.target.shift(-1, fill_value=0) == 0))].index
      
      # group change points into pairs, e.g. [1, 3, 4, 10] -> [(1, 3), (4, 10)]
      groups_ = list(zip(change_points[::2], change_points[1::2]))
      
      # keep only groups of minimal length
      groups = [(a, b) for a, b in groups_ if b - a + 1 >= n]
      

      所提供输入数据的groups 的值为[(2, 4), (9, 11), (31, 36)]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-22
        • 2018-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-12
        相关资源
        最近更新 更多