【问题标题】:Group dataframe according to start and stop columns根据开始和停止列对数据框进行分组
【发布时间】:2021-06-17 12:05:03
【问题描述】:

我想根据 start 和 stop 列对 pandas Dataframe 进行剪切/分组,但仅限于 start->stop 的情况。

我想要从“开始”非零值到“停止”非零值的索引范围。但仅当“开始”非零值后跟“停止”非零值时。从上到下遍历索引

我附上了一些代码,创建了问题的简化版本和相应的图像。

col1 = np.zeros(10)
col2 = np.zeros(10)
col1[[0, 1, 5, 8]] = 1
col2[[3, 6, 7, 9]] = 1

df = pd.DataFrame({'start': col1, 'stop': col2})

所需的输出将索引分组,有点像: [(1,2,3), (5,6), (8,9)]

附加信息以防万一这会简化事情:

  1. 合并列就可以了。
  2. 我的原始数据框有一个 pd.TimedeltaIndex。

预期结果的视觉澄清:

【问题讨论】:

  • 那么,你需要 delta btw 列,对吧?为什么不从另一列中减去一列并将其存储为新列? - 然后你可以过滤掉!=0的值
  • 我不需要行之间的(时间)增量,但特定行的范围 - 要么用会话号 0、1、2、3 等标记它们,要么直接将它们分组以进行 groupby 的计算(grouper/cut 等)。
  • 对不起,没看懂要求,它的范围是从第一个start非零值到第一个stop非零值,不是吗?
  • 对不起,造成混乱。我想要从“开始”非零值到“停止”非零值的索引范围。但仅当“开始”非零值后跟“停止”非零值时。从上到下遍历索引。
  • 我添加了对我想要实现的目标的视觉说明。我希望这会有所帮助。

标签: python pandas dataframe


【解决方案1】:

首先我们需要查看startstop的区间,找出哪些是“有效”区间结束:

>>> ends = df.index.to_series().where(df['stop'].ne(0))
>>> starts = df.index.to_series().where(df['start'].ne(0))
>>> ends
0    NaN
1    NaN
2    NaN
3    3.0
4    NaN
5    NaN
6    6.0
7    7.0
8    NaN
9    9.0
dtype: float64
>>> starts
0    0.0
1    1.0
2    NaN
3    NaN
4    NaN
5    5.0
6    NaN
7    NaN
8    8.0
9    NaN
dtype: float64

现在我们可以尝试为每个有效开始获取下一个有效结束:

>>> next_end = ends.bfill().rename('end')
>>> valid_starts = starts.dropna().rename('start')
>>> candidates = valid_starts.to_frame().join(next_end, how='left')
>>> candidates
   start  end
0    0.0  3.0
1    1.0  3.0
5    5.0  6.0
8    8.0  9.0

这里我们看到从 0 开始的间隔存在问题:另一个间隔稍后开始(在 1),因此 [0, 3] 无效,我们应该只保留 [1, 3]。这可以通过 groupby + max 来完成,例如:

>>> intervals = candidates.groupby('end')['start'].max().reset_index().astype(int)
>>> intervals
   end  start
0    3      1
1    6      5
2    9      8

最后从端点生成索引列表很容易:

>>> intervals.agg(lambda s: list(range(s['start'], s['end'] + 1)), axis='columns')
0    [1, 2, 3]
1       [5, 6]
2       [8, 9]
dtype: object

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多