我试图通过对具有固定增量(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)以及该窗口的sum作为行存储在新的数据帧中(具有重叠的窗口)合并)。注意:窗口理论上也可以从0/1开始,以max(End)结束。
最优化的方法是什么(使用pandas,numpy或scikit-learn)?
编辑:我制作了一个大致描述我想要的图表。在我的例子中,pandas数据帧实际上描述了一条长行的段*。我想要的是另一个数据帧,如果窗口中的段总和超过阈值,我得到最左边的段的开始和最右边的段的结束到新的数据帧。 * - (如果我们认为count列只包含一个)
注意:我问过Julia的类似问题,现在已被删除。这可以被认为类似于聚类,唯一的区别是聚类是在一条线而不是两个或维上创建的,并且点之间的距离只是坐标的减法。
好的 - 我正在尝试发布我制作的临时解决方案:并不是真的建议任何人尝试它。
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(结束)结束的数据帧 - 这一步非常低效且占用内存。在这种情况下,长度由每个唯一chr的数组定义。在下一步中,我将命中(计数)分配给与我的输入数据帧匹配的位置 - 基于起始位置。在最后一步中,我通过每次切片1000行然后总结命中来遍历扩展的数据帧。对于匹配的窗口或数据帧切片,我采用最小和最大坐标并将它们存储在一个数组中。 Buggy,效率极低且冗余的代码,但不知何故在最低级别工作。