【问题标题】:What is an efficient method using pandas for retrieving data with a given start/end point when the datapoints also have start/end points?当数据点也有起点/终点时,使用 pandas 检索具有给定起点/终点的数据的有效方法是什么?
【发布时间】:2021-08-08 02:14:57
【问题描述】:

我目前正在开发一个利用基因组计数数据的应用程序。此数据被加载到 pandas 数据框中。此数据的示例如下所示:

chrom chromStart chromEnd height
chr3 93504854 93504940 0
chr3 93504940 93504977 1
chr3 93504977 93505016 2
chr3 93505016 93505018 1
chr3 93505018 93505053 2
chr3 93505053 93505093 1
chr3 93505093 93505151 0
chr3 93505151 93505227 1
chr3 93505227 93505252 0
chr3 93505252 93505328 1

我目前有一个标题的实现,这占了我相当多的时间。这是实现:

def checkInBounds(row, chrom, chromStart, chromEnd):
    try:
        if not chrom == row['chrom']:
            return False
    except KeyError:
        print('row count', row.count)
        print("CheckInBoundsKeyError\nRow\n", row, '\n chrom', chrom, 'start', chromStart, 'end', chromEnd)
        return False

    if chromStart <= row['chromStart'] <= chromEnd:
        return True
    elif chromStart <= row['chromEnd'] <= chromEnd:
        return True
    else:
        return (row['chromStart'] < chromEnd) and (row['chromEnd'] > chromEnd)

这是使用如下所示的 apply 语句运行的:

df.apply(checkInBounds, axis=1, args=(chrom, start, end))

有没有更快的方法来完成同样的任务?

【问题讨论】:

标签: python python-3.x pandas data-science


【解决方案1】:

这里是使用 pandas 系列中的searchedsorted 函数的解决方案。在排序后的 Series 中,它会告诉您应该将传递的值放在哪里以保持数据排序。

对我得到的数据使用你的函数:

chrom = 'chr3'
start = 93504854
end = 93505053
df = df.sort_values(['chrom','chromStart','chromEnd'])
df.apply(checkInBounds, axis=1, args=(chrom, start, end))

    0     True
    1     True
    2     True
    3     True
    4     True
    5     True
    6    False
    7    False
    8    False
    9    False

这是搜索排序的功能。

def checkInBounds_new(df, start, end, chrom):
    bound1 = df.chromStart.searchsorted(start)
    bound2 = df.chromStart.searchsorted(end)
    df =  df.loc[bound1:bound2]
    return df[df['chrom'] == chrom]
checkInBounds_new(df, start, end, chrom):

给你:

chrom   chromStart  chromEnd    height
0   chr3    93504854    93504940    0
1   chr3    93504940    93504977    1
2   chr3    93504977    93505016    2
3   chr3    93505016    93505018    1
4   chr3    93505018    93505053    2
5   chr3    93505053    93505093    1

注意这两个函数基本上是如何返回这些输入的前 5 行。另外,我在这里没有执行任何检查,比如确保 end > start 等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-20
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多