【问题标题】:Pandas - drop overlapping ranges in dataframePandas - 在数据框中删除重叠范围
【发布时间】:2019-12-10 23:44:46
【问题描述】:

具有以下形式的数据框:

df = pd.DataFrame({
                'A': ('foo', 'foo', 'foo', 'foo', 'foo'),
                'start': (3039, 3536, 9140, 12976, 14982),
                'end': (3536, 4879, 44331, 13641, 15643)
                 })

    A   start   end
0   foo 3039    3536
1   foo 3536    4879
2   foo 9140    44331
3   foo 12976   13641
4   foo 14982   15643

如何删除由startend 列确定的“范围”与其他行重叠的所有行?在上面的示例中,索引为34 的行将被删除,因为它们包含在行索引2 中。

我尝试从shift() 开始尝试创建一个掩码系列,但除了因为所有值都是False 而无法工作之外,它只会与前一行进行比较,而我想比较所有行的范围。

ranges_mask = ((df['start'] > df['start'].shift(-1)) & (df['end'] < df['end'].shift(-1)))

【问题讨论】:

  • 如果例如 end of 3 大于 end of 2 我们应该怎么做?

标签: pandas dataframe


【解决方案1】:

这里有一个解决方案 我们只考虑完全在另一个区间内的情况:

df2=df.copy()
groups=pd.Series([1]*len(df))
while (groups.value_counts()>1).any():
    groups=( df2['start'].gt(df2['start'].shift())  &
             df2['end'].gt(df2['end'].shift()) ).cumsum()
    print(groups)
    df2=df2.groupby(groups,as_index=False).first()

print(df2)

输出

0    0
1    1
2    2
3    2
4    3
dtype: int64
0    0
1    1
2    2
3    2
dtype: int64
0    0
1    1
2    2
dtype: int64
     A  start    end
0  foo   3039   3536
1  foo   3536   4879
2  foo   9140  44331

【讨论】:

  • 数据框是否需要按start 排序才能使此解决方案起作用?
  • 好的,只是认为必须对原始数据框进行排序才能使其正常工作。一个简单的.sort_values('start').reset_index(drop=True) 应该可以。
  • 如果它们很乱,并且您想按开始排序应用它,那么如果有必要订购。很高兴为您提供帮助:)
猜你喜欢
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2021-09-22
相关资源
最近更新 更多