pythonでのデータ処理


下記のデータに対してtag 'a'のstart-endのデータに対して 'b'のstart-
endで重複する部分を削除したいのですがどのような処理をしたら良いでしょうか。

[code]

    import pandas as pd
    
    data = [
        ['a', 1, 10],
        ['b', 2, 3],
        ['b', 4, 6],
        ['b', 9, 11]
    ]
    columns = ['tag', 'start', 'end']
    df = pd.DataFrame(data, columns=columns)
    
[/code]

**期待する結果:**

[code]

    result = [
        ['a', 1, 2]
        ['b', 2, 3]
        ['a', 3, 4]
        ['b', 4, 6]
        ['a', 6, 9]
        ['b', 9, 11]
    ]
    result_df = pd.DataFrame(result, columns=columns)
    
[/code]




以下のようにオーバーラップがあるとその後の処理が大変そうなので  
そのようなオーバーラップも隣り合うデータもないものとして回答します

| tag | start | end  
---|---|---|---  
0 | b | 2 | 5  
1 | b | 3 | 4  
2 | b | 3 | 6  
3 | b | 6 | 7  
  
* * *

Pythonで `zip`など用いる方法

[code]

    >>> lst = sorted([(2, 3), (4, 6), (9, 11)], key=lambda v: v[0])
    >>> lst
    [(2, 3), (4, 6), (9, 11)]
    >>> stop, start = zip(*lst)
    >>> start
    (3, 6, 11)
    >>> stop
    (2, 4, 9)
    >>> list(zip((1,) +start, stop))
    [(1, 2), (3, 4), (6, 9)]
    
[/code]

既存の `df`と合成

[code]

    >>> df[df.tag == 'b']
      tag  start  end
    1   b      2    3
    2   b      4    6
    3   b      9   11
    >>> tmp = pd.DataFrame(list(zip((1,) +start, stop)), columns=['start', 'end'])
    >>> tmp['tag'] = 'a'
    >>> ndf = pd.concat([df[df.tag == 'b'], tmp])
    >>> ndf.sort_values('start')
      tag  start  end
    0   a      1    2
    1   b      2    3
    1   a      3    4
    2   b      4    6
    2   a      6    9
    3   b      9   11
    
[/code]

上のコードでは `(1, 10)` 固定なので, こんな風に

[code]

    >>> r = range(1, 10)
    >>> if stop[0] > r.start:
    ...     start = (r.start,) +start
    ... else:
    ...     stop = stop[1:]
    ...
    >>> if start[-1] < r.stop:
    ...     stop += (r.stop,)
    ...
    >>> list(zip(start, stop))
    [(1, 2), (3, 4), (6, 9)]
    >>>
    
[/code]

