如果在Python中范围重叠时如何添加列的值

时间:2018-05-22 21:57:08

标签: python pandas

我有这张桌子:

    id   start  end  stg
0   ZZ   0      25   5.0
1   ZZ   10     65   7.0
2   ZZ   30     50   2.0
3   ZZ   50     60   3.0
4   BB   0      2    5.6
5   BB   5      8    6.6
6   BB   8      13   18.0

我想在" stg"中添加值如果范围[start,end]中存在重叠并创建新范围和stg。输出应该如下所示:

    id   start  end  stg
0   ZZ   0      10   5
1   ZZ   10     25   12
2   ZZ   25     30   7
3   ZZ   30     50   9
4   ZZ   50     60   10
5   ZZ   60     65   7
6   BB   0      5    5.6
7   BB   5      8    6.6
8   BB   8      13   18.0

1 个答案:

答案 0 :(得分:1)

这只是部分解决方案,因为它完全忽略id。使用IntervalIndex

示例数据

df = pd.DataFrame({'id': ['ZZ'] * 4, 
                   'start': [0, 10, 30, 50], 
                   'end': [25, 65, 50, 60], 
                   'stg': [5.0, 7.0, 2.0, 3.0]})
df = df[['id', 'start', 'end', 'stg']]

df
   id  start  end  stg
0  ZZ      0   25  5.0
1  ZZ     10   65  7.0
2  ZZ     30   50  2.0
3  ZZ     50   60  3.0

获取由起始值和结束值定义的最小子区间

subints = pd.IntervalIndex.from_breaks(sorted(np.unique(df[['start', 'end']].values.flatten())))
subints
IntervalIndex([(0, 10], (10, 25], (25, 30], (30, 50], (50, 60], (60, 65]]
              closed='right',
              dtype='interval[int64]')

在原始DF

上设置IntervalIndex
idx = pd.IntervalIndex.from_arrays(df['start'], df['end'])
df.set_index(idx, inplace=True)
df
          id  start  end  stg
(0, 25]   ZZ      0   25  5.0
(10, 65]  ZZ     10   65  7.0
(30, 50]  ZZ     30   50  2.0
(50, 60]  ZZ     50   60  3.0

在列表推导中使用IntervalIndex切片

result = pd.DataFrame([(s.left, s.right, df2.loc[s]['stg'].sum()) 
                       for s in subints], 
                      columns=['start', 'end', 'stg'])
result
   start  end   stg
0      0   10   5.0
1     10   25  12.0
2     25   30   7.0
3     30   50   9.0
4     50   60  10.0
5     60   65   7.0