在Python中,当范围重叠时,如何添加列的值
我有这张桌子:在Python中,当范围重叠时,如何添加列的值,python,pandas,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 如果范围[start,end]中存在重叠,我想在“stg”中添加值,并创建新的范
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
如果范围[start,end]中存在重叠,我想在“stg”中添加值,并创建新的范围和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
这只是部分解决方案,因为它完全忽略了
id
。使用IntervalIndex
:
示例数据
获取由起始值和结束值定义的最小子间隔
在原始DF上设置IntervalIndex
在列表中使用IntervalIndex切片
我不认为有一种方法可以通过广播(一次表)操作来实现这一点,这种方法比仅仅迭代更有效。(尽管可能会出现一个Pandas向导并与之相矛盾。)所以只需编写一个易于理解的显式循环,该循环将适用于任何序列或区间数(或者使用PyPI中的区间库)。如果你被卡住了,当然,带着一个特定的问题回到这里,但这应该很容易。问题是我甚至不知道如何编写循环!你能发文本而不是图片吗?另外,我不确定预期的输出数据帧是否完全准确。预期输出中缺少值60,输入中没有值75、80和110。@AntonvBR我已将其作为代码发布。彼得,对不起,你是对的!我更正了表格(由于手工计算,它仍然可能有错误),我希望这个想法是清楚的。太好了!刚刚注意到一个错误:其中一个间隔是
(50,50]
,我猜这不会有什么帮助哈哈。很快将编辑一个更正。我可以接受;-)因为我正在绘制这些范围,单点不会影响我的结果。但是提前谢谢你修改代码。@geek2000,很高兴听到这个消息。修正了,我认为:P(添加了np.unique
)
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]')
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
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