作为更大数据集的一部分,我有一个
DataFrame
组织如下:
Chromosome arm Start End ratio_median
5 5.5 96100001 96150000 -0.582
5 5.5 96150001 96200000 -0.582
5 5.5 96200001 96250000 -0.582
5 5.5 96250001 96300000 -0.582
5 5.5 96300001 96350000 -0.582
这里的目标是将具有相同
Chromosome
、arm
和 ratio_median
的行分组,并使用 Start
的最小值和 End
的最大值形成更大的间隔。
它看起来像是一个可以用
groupby
解决的沼泽标准问题:
grouped = df.groupby(by=["Chromosome", "arm", "ratio_median"]).agg(
{"Chromosome": "first", "Start": "min", "End": "max", "ratio_median": "first"})
但是,由于这些是坐标,因此分组应该只考虑具有公共分组键的连续组,而不是整个数据集。事实上,这种方法可以完美地工作,直到你有具有相同值的间隔,这些间隔被一个或多个具有不同键的间隔分隔开(主要是
ratio_median
作为判别元素)。例如,从这些数据开始:
Chromosome arm Start End ratio_median
5 5.5 96150001 96200000 -0.582
5 5.5 96200001 96250000 -0.582
5 5.5 96250001 96300000 -0.582
5 5.5 96300001 96350000 -0.582
5 5.5 102600001 102650000 -0.014
5 5.5 102650001 102700000 -0.014
5 5.5 102700001 102750000 -0.014
5 5.5 102750001 102800000 -0.014
5 5.5 102800001 102850000 -0.014
5 5.5 103700001 103750000 -0.582
5 5.5 103750001 103800000 -0.582
5 5.5 103800001 103850000 -0.582
5 5.5 103850001 103900000 -0.582
5 5.5 103900001 103950000 -0.582
这里有三个单独的间隔:但是用
groupby
分组会将第三个间隔与第一个间隔混在一起(正确:它按预期工作):
Chromosome arm Start End ratio_median
5 5.5 96100001 103950000 -0.582
5 5.5 102600001 102850000 -0.014
从坐标的角度来看,这是不正确的,因为它们不应该像这样重叠:只有具有相同分组键的连续行才应该被聚合。正确的预期结果应该是:
Chromosome arm Start End ratio_median
5 5.5 96100001 96350000 -0.582
5 5.5 102600001 102850000 -0.014
5 5.5 103700001 103950000 -0.582
但是,我不知道如何在 pandas 中正确执行此操作,也不知道如何使用其他特定于域的库(如
PyRanges
或 bioframe
)来正确执行此操作。我已经尝试过 PyRanges.cluster()
但另一方面,以不同的方式分配 ID,并且得到的间隔更小。
我的猜测是这里需要某种形式的迭代,但是最好的方法是什么?我单独尝试过
groupby
,但再次遇到上述问题。
您可以将每组的结束与移动的开始进行比较,以形成新的石斑鱼:
g = (df.sort_values(by=['Start', 'End'])
.groupby(['Chromosome', 'arm', 'ratio_median'])['End']
.transform(lambda s: s.shift().rsub(df['Start']).gt(1).cumsum())
)
out = (df
.groupby(['Chromosome', 'arm', 'ratio_median', g], as_index=False)
.agg({'Start': 'min', 'End': 'max'})
)