我有一个名为df的Pandas DataFrame,其列名为“ step”,它只是一个增量计数器(1、2、3、4等):

step col1 col2
1    2    3
2    3    5
3    1    0
4    8    9
5    2    3


我正在从df选择一些感兴趣的行:

    work_df = df[df[col1] < df[col2]]

step col1 col2
1    2    3
2    3    5
4    8    9
5    2    3



现在,我应该通过“ step”的连续性将work_df拆分为一些sub_df(即,如果work_df['step'] == [1,2,3,7,8,9][1,2,3]属于sub_df_1[7,8,9]属于sub_df_2等),目前我正在这样做这条路:

        for idx, row in work_df.iterrows():
            if row['step'] > prev_step + 1:
                if step_count > 1: #don't want to have df with only 1 row
                    interval_list.append({'step_count': step_count ... })
                step_count = 0
            else:
                step_count += 1
            prev_step = row['step']


我正在根据来自interval_list的信息构建新的sub_df。但是我不确定这是否是实现我真正需要的最佳方法:

sub_df1=
step col1 col2
1    2    3
2    3    5

sub_df2=
step col1 col2
4    8    9
5    2    3


是否有更好的方法通过列的连续性拆分DataFrame?

最佳答案

您可以在此处按(df[col] != df[col].shift(1)+1).cumsum()分组,也可以按@MarkWang says df['data'].diff().ne(1).cumsum()分组。确实,如果我们使用您的样本数据:

>>> df
   data
0     1
1     2
2     3
3     7
4     8
5     9


那么此表达式将产生:

>>> df['data'].diff().ne(1).cumsum()
0    1
1    1
2    1
3    2
4    2
5    2
Name: data, dtype: int64


因此,我们可以在这些值上执行groupby

>>> list(df.groupby(df['data'].diff().ne(1).cumsum()))
[(1,    data
0     1
1     2
2     3), (2,    data
3     7
4     8
5     9)]


因此,我们这里有两组:[1,2,3][7,8,9]。因此,您可以在这里获得两个组:

>>> (__, sub_df_1), (__, sub_df_2) = df.groupby(df['data'].diff().ne(1).cumsum())
>>> sub_df_1
   data
0     1
1     2
2     3
>>> sub_df_2
   data
3     7
4     8
5     9


或您提供的第二个样本数据片段:

>>> (__, sub_df1), (__, sub_df2) = df2.groupby(df2['data'].diff().ne(1).cumsum())
>>> sub_df1
   step  col1  col2
0     1     2     3
1     2     3     5
>>> sub_df2
   step  col1  col2
2     4     8     9
3     5     2     3


例如,您可以在此处使用列表推导或itemgetter来获取相应的组。例如:

>>> [g[1] for g in df2.groupby(df2['step'].diff().ne(1).cumsum())]
[   step  col1  col2
0     1     2     3
1     2     3     5,    step  col1  col2
2     4     8     9
3     5     2     3]


您也可以使用1删除长度的组:

>>> [g[1] for g in df2.groupby(df2['step'].diff().ne(1).cumsum()) if len(g[1]) > 1]
[   step  col1  col2
0     1     2     3
1     2     3     5,    step  col1  col2
2     4     8     9
3     5     2     3]


因此,此列表包含两个子组。我强烈建议不要按名称分配。是的,它是strictly speaking possible。但这是一种反模式,通常弊大于利。

关于python - 如何检查DataSeries的连续性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57539975/

10-11 10:26