【问题标题】:Pandas rolling dataframe to create clustersPandas 滚动数据框以创建集群
【发布时间】:2019-02-03 05:31:17
【问题描述】:

我正在尝试通过对具有固定增量 (y) 的特定窗口大小 (x) 进行累积总和来在 python 中创建一个数据框,如果总和大于预定义值 (z),我想添加值(取决于列)到另一个数据框。我可以使用大量的 for 循环来执行此操作,但这似乎效率低下。

为了详细描述问题,这是我的数据框的样子:

│ Start  │ End    │ Count │
├────────┼────────┼───────┤
│ 49076  │ 49095  │ 1     │
│ 50296  │ 50318  │ 1     │
│ 53291  │ 53308  │ 1     │
│ 56213  │ 56232  │ 3     │
│ 86489  │ 86508  │ 13    │
│ 86489  │ 86508  │ 7     │
│ 150696 │ 150713 │ 1     │
│ 174807 │ 174824 │ 1     │
│ 192491 │ 192508 │ 1     │
│ 203977 │ 203996 │ 1     │
│ 269679 │ 269696 │ 1     │
⋮

并且窗口在 Start 上运行,而不是在行上运行。这意味着如果窗口是 10000 (x),那么第一个窗口将从 49076 开始,到 59076 结束。随着 1000 (y) 的增加,第二个窗口将从 50076 开始,到 60076 结束,依此类推。现在,如果在这些窗口中的任何一个 Count 列的总和超过阈值 (z),我希望 min(Start) 和 max(End) 以及该窗口的总和存储为新数据帧中的行(具有重叠窗口合并)。 注意:窗口理论上也可以从 0/1 开始,到 max(End) 结束。

最优化的方法是什么(使用 pandas、numpy 或 scikit-learn)?

编辑:我做了一个图表来大致描述我想要什么。就我而言,熊猫数据框实际上是在描述长线的段*。我想要的是另一个数据帧,如果窗口中的段总和超过阈值,我将最左边段的开始和最右边段的结束放入一个新的数据帧中。 *-(如果我们认为 count 列只包含一个)

注意:我向 Julia 提出了一个类似的问题,该问题现已被删除。这可以被认为类似于聚类,唯一的区别是聚类是在一条线上而不是二维或维度上创建的,并且点之间的距离只是坐标的减法。

【问题讨论】:

  • 你能添加一个预期输出的例子吗?如果可能的话,一个涵盖你想要的所有东西的完整示例是很棒的。
  • @QusaiAlothman ,我试图创建一个描述问题的图表。如果您需要更多说明,请告诉我。
  • 好的,我现在得到了你想要的,但遗憾的是,没有办法使用 pandas 或 numpy(我不知道)现成的来做到这一点。在日期时间列上使用滚动窗口有一种“hacky”方式,但我不确定性能。我建议你坚持你的实施,但我会提供我的供你尝试。
  • @QusaiAlothman,我不确定日期时间列是否有意义。本质上,只有 row[start] 才是最重要的。到目前为止,我已经能够识别 sum > x 的窗口,但不能识别这些窗口的开始和结束。

标签: python pandas numpy dataframe scikit-learn


【解决方案1】:

好的 - 我正在尝试发布我制作的临时解决方案:并不是真的推荐任何人尝试它。

for i in positiveFrame.chr.unique():
    workingFrame = positiveFrame[positiveFrame['chr'] == i]
    totalPeaks = workingFrame['count'].sum()
    # print ("Total amount of peaks in contig: ", i, ": ", totalPeaks)
    if totalPeaks < minimumSum:
        continue
    hits = workingFrame.start.tolist()
    runningFrame = pd.DataFrame({'start': range(1, lengthFile[str(i)]), 'hit': 0})
    runningFrame.loc[runningFrame.start.isin(hits), ['hit']] = 1
    for k in range(0, runningFrame.shape[0], incrementSize):
        z = runningFrame[k:k + incrementSize]
        if (z['hit'].sum() > 49):
            #print("banzai\n")
            positiveClusterChr.append(i)
            positiveClusterStart.append(z['hit'].eq(1).idxmax())
            positiveClusterEnd.append(z.hit[::-1].idxmax())

这里本质上发生的是,我正在创建另一个数据帧,其坐标从 0 开始并以 max(End) 结束 - 此步骤非常低效且消耗内存。在这种情况下,长度由每个唯一字符的数组定义。在下一步中,我将根据起始位置将命中(计数)分配给与我的输入数据帧匹配的位置。在最后一步中,我通过每次切片 1000 行然后对命中求和来遍历扩展的数据帧。对于匹配的窗口或数据框切片,我将获取最小和最大坐标并将它们存储在一个数组中。 错误、效率极低和冗余的代码,但不知何故在最低水平上工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2019-06-28
    • 2018-11-03
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    相关资源
    最近更新 更多