pandas 中的区间交集

Interval intersection in pandas

更新 5:

此功能已作为 pandas 20.1 的一部分发布(在我生日那天 :])

更新 4:

PR 已合并!

更新 3:

The PR has moved here

更新 2:

这个问题似乎对 re-opening the PR for IntervalIndex in pandas 有帮助。

更新:

我不再有这个问题,因为我现在实际上是在查询 AB 的重叠范围,而不是 B 中落在 [= 范围内的点11=],这是一个全区间树问题。不过我不会删除这个问题,因为我认为它仍然是一个有效的问题,而且我没有很好的答案。

问题陈述

我有两个数据框。

在数据帧A中,两个整数列合在一起代表一个区间。

在数据框B中,一个整数列代表一个位置。

我想进行某种连接,以便将点分配给它们所在的每个间隔。

间隔很少但偶尔会重叠。如果一个点落在该重叠范围内,则应将其分配给两个间隔。大约一半的点不会落在一个区间内,但几乎每个区间都会在其范围内至少有一个点。

我一直在想什么

我最初打算从 pandas 中转储我的数据并使用 intervaltree or banyan or maybe bx-python but then I came across this gist. It turns out that the ideas shoyer has in there never made it into pandas, but it got me thinking -- it might be possible to do this within pandas, and since I want this code to be as fast as python can possibly go, I'd rather not dump my data out of pandas until the very end. I also get the feeling that this is possible with bins and pandas cut 函数,但我是 pandas 的新手,所以我可以使用一些指导!谢谢!

备注

可能相关? Pandas DataFrame groupby overlapping intervals of variable length

此功能作为 pandas 20.1

的一部分发布

使用 pyranges 作答,基本上 pandas 撒上生物信息学糖。

设置:

import numpy as np
np.random.seed(0)
import pyranges as pr

a = pr.random(int(1e6))
# +--------------+-----------+-----------+--------------+
# | Chromosome   | Start     | End       | Strand       |
# | (category)   | (int32)   | (int32)   | (category)   |
# |--------------+-----------+-----------+--------------|
# | chr1         | 8830650   | 8830750   | +            |
# | chr1         | 9564361   | 9564461   | +            |
# | chr1         | 44977425  | 44977525  | +            |
# | chr1         | 239741543 | 239741643 | +            |
# | ...          | ...       | ...       | ...          |
# | chrY         | 29437476  | 29437576  | -            |
# | chrY         | 49995298  | 49995398  | -            |
# | chrY         | 50840129  | 50840229  | -            |
# | chrY         | 38069647  | 38069747  | -            |
# +--------------+-----------+-----------+--------------+
# Stranded PyRanges object has 1,000,000 rows and 4 columns from 25 chromosomes.
# For printing, the PyRanges was sorted on Chromosome and Strand.

b = pr.random(int(1e6), length=1)
# +--------------+-----------+-----------+--------------+
# | Chromosome   | Start     | End       | Strand       |
# | (category)   | (int32)   | (int32)   | (category)   |
# |--------------+-----------+-----------+--------------|
# | chr1         | 52110394  | 52110395  | +            |
# | chr1         | 122640219 | 122640220 | +            |
# | chr1         | 162690565 | 162690566 | +            |
# | chr1         | 117198743 | 117198744 | +            |
# | ...          | ...       | ...       | ...          |
# | chrY         | 45169886  | 45169887  | -            |
# | chrY         | 38863683  | 38863684  | -            |
# | chrY         | 28592193  | 28592194  | -            |
# | chrY         | 29441949  | 29441950  | -            |
# +--------------+-----------+-----------+--------------+
# Stranded PyRanges object has 1,000,000 rows and 4 columns from 25 chromosomes.
# For printing, the PyRanges was sorted on Chromosome and Strand.

执行:

result = a.join(b, strandedness="same")
# +--------------+-----------+-----------+--------------+-----------+-----------+--------------+
# | Chromosome   | Start     | End       | Strand       | Start_b   | End_b     | Strand_b     |
# | (category)   | (int32)   | (int32)   | (category)   | (int32)   | (int32)   | (category)   |
# |--------------+-----------+-----------+--------------+-----------+-----------+--------------|
# | chr1         | 227348436 | 227348536 | +            | 227348516 | 227348517 | +            |
# | chr1         | 18901135  | 18901235  | +            | 18901191  | 18901192  | +            |
# | chr1         | 230131576 | 230131676 | +            | 230131636 | 230131637 | +            |
# | chr1         | 84829850  | 84829950  | +            | 84829903  | 84829904  | +            |
# | ...          | ...       | ...       | ...          | ...       | ...       | ...          |
# | chrY         | 44139791  | 44139891  | -            | 44139821  | 44139822  | -            |
# | chrY         | 51689785  | 51689885  | -            | 51689859  | 51689860  | -            |
# | chrY         | 45379140  | 45379240  | -            | 45379215  | 45379216  | -            |
# | chrY         | 37469479  | 37469579  | -            | 37469576  | 37469577  | -            |
# +--------------+-----------+-----------+--------------+-----------+-----------+--------------+
# Stranded PyRanges object has 16,153 rows and 7 columns from 24 chromosomes.
# For printing, the PyRanges was sorted on Chromosome and Strand.

df = result.df
#       Chromosome      Start        End Strand    Start_b      End_b Strand_b
# 0           chr1  227348436  227348536      +  227348516  227348517        +
# 1           chr1   18901135   18901235      +   18901191   18901192        +
# 2           chr1  230131576  230131676      +  230131636  230131637        +
# 3           chr1   84829850   84829950      +   84829903   84829904        +
# 4           chr1  189088140  189088240      +  189088163  189088164        +
# ...          ...        ...        ...    ...        ...        ...      ...
# 16148       chrY   38968068   38968168      -   38968124   38968125        -
# 16149       chrY   44139791   44139891      -   44139821   44139822        -
# 16150       chrY   51689785   51689885      -   51689859   51689860        -
# 16151       chrY   45379140   45379240      -   45379215   45379216        -
# 16152       chrY   37469479   37469579      -   37469576   37469577        -
# 
# [16153 rows x 7 columns]