在熊猫的坐标行中只保留最大间隔

chi*_*tra 5 python python-3.x pandas pandas-groupby

我有一个数据框,例如:

   Groups Name start end  sum
1      G1    A   451 954 1405
2      G1    B   451 951 1402
3      G1    C   451 969 1420
4      G1    D   463 870 1333
5      G1    E   463 888 1351
6      G1    X   230 450  680
7      G1    Z   229 450  681
8      G2    F   119 841  960
9      G2    G   118 842  960
10     G3    H   460 790 1250
11     G3    I   123 300 177
12     G4    J   343 878 1221
13     G4    K   343 878 1221
14     G4    L   320 862 1182
Run Code Online (Sandbox Code Playgroud)

我希望每个组只保留一个区间代表(一个区间意味着df.startdf.end行之间的重叠),我解释一下:

例如,在G1 中2 个间隔组

间隔 1(带有min = 451max = 969):

Name start end sum
A    451   954 1405
B    451   951 1402
C    451   969 1420
D    463   870 1333
E    463   888 1351
Run Code Online (Sandbox Code Playgroud)

然后我取最大的df.sum(这里1420

间隔 2 (带min = 229max = 450

Name start end  sum
X    230   450  680
Z    229   450  681
Run Code Online (Sandbox Code Playgroud)

然后我取最大的df.sum(这里681

如果我对整个数据框这样做,我会得到:

   Groups Name start end  sum
3      G1    C   451 969 1420
7      G1    Z   229 450  681
9      G2    G   118 842  960
10     G3    H   460 790 1250
11     G3    I   123 300 177
12     G4    J   343 878 1221
Run Code Online (Sandbox Code Playgroud)

Does someone have an idea?
Here are the data in dictionary format :

{'Groups Name start end  sum': {0: 'G1    A   451 954 1405', 1: 'G1    B   451 951 1402', 2: 'G1    C   451 969 1420', 3: 'G1    D   463 870 1333', 4: 'G1    E   463 888 1351', 5: 'G1    X   230 450  680', 6: 'G1    Z   229 450  681', 7: 'G2    F   119 841  960', 8: 'G2    G   118 842  960', 9: 'G3    H   460 790 1250', 10: 'G3    I   123 300 177', 11: 'G4    J   343 878 1221', 12: 'G4    K   343 878 1221', 13: 'G4    L   320 862 1182'}}
Run Code Online (Sandbox Code Playgroud)

Sha*_*ica 2

Groups您可以按列和表示重叠范围的新列对数据框进行分组。Groups您可以做的是首先按和对数据帧进行排序end(以及start中是否有重复项end)。

df = df.sort_values(['Groups', 'end', 'start'])
Run Code Online (Sandbox Code Playgroud)

现在,由于我们知道行的顺序,因此我们可以创建上面提到的附加列,我们将其称为overlap

c1 = df['Groups'].shift() != df['Groups']
c2 = df['end'].shift() - df['start'] < 0
df['overlap'] = (c1 | c2).cumsum()
Run Code Online (Sandbox Code Playgroud)

当前数据框:

Groups Name  start  end   sum  overlap
7      G1    Z    229  450   681        1
6      G1    X    230  450   680        1
4      G1    D    463  870  1333        2
5      G1    E    463  888  1351        2
2      G1    B    451  951  1402        2
1      G1    A    451  954  1405        2
3      G1    C    451  969  1420        2
8      G2    F    119  841   960        3
9      G2    G    118  842   960        3
11     G3    I    123  300   177        4
10     G3    H    460  790  1250        5
14     G4    L    320  862  1182        6
12     G4    J    343  878  1221        6
13     G4    K    343  878  1221        6
Run Code Online (Sandbox Code Playgroud)

sum最后,我们使用 获得每组中具有最大值的行groupby

df.sort_values(['sum'], ascending=False).groupby('overlap').first()
Run Code Online (Sandbox Code Playgroud)

结果:

        Groups Name  start  end   sum
overlap                              
1           G1    Z    229  450   681
2           G1    C    451  969  1420
3           G2    F    119  841   960
4           G3    I    123  300   177
5           G3    H    460  790  1250
6           G4    J    343  878  1221
Run Code Online (Sandbox Code Playgroud)

对于选择sum组中 相同的行,可以在按 进行sum二级排序时使用附加列。例如,如果顺序应基于行的原始顺序,则index可以使用 在开头添加新列reset_index()