我没有得到这个部分:
...如果连续开始-停止对的 chr 相同。
我仍然给你写了一些代码,这些代码在某些方面与你给定的表格相同。如果您澄清您的观点,我可能会更新该答案。也许它仍然对您有所帮助,并且您可以将缺少的部分放入:
import pandas as pd
import numpy as np
df = pd.DataFrame({'region_name': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], 'start' : [1913, 46430576, 52899183, 58456122, 62925929, 65313395, 65511483, 65957829], 'stop' : [90207973, 90088654, 90088654, 74708723, 84585795, 90081985, 90096995, 83611443], 'chr':[1, 1, 1, 1, 1, 1, 1, 2]})
# store texts for each row in that list
overlaps_texts = []
# iterate over all rows
for i, row in df.iterrows():
# extract entries' data
start, stop, ch = row[1:4]
# Check if I am completely inside (nested into something)
# Note that this will always return indexers where each entry if True or False
# So nested will be something like [False, False, True, ...] where True means
# that start > start_other AND stop < stop_other (="I am nested")
nested = ((start > df.loc[:, 'start']) & (stop < df.loc[:, 'stop']))
# hanging out left
overlap_1 = ((stop > df.loc[:, 'start']) &
(stop < df.loc[:, 'stop'])
)
# starting before stop of other but ending after (hanging out right)
overlap_2 = ((start < df.loc[:, 'stop']) & (start > df.loc[:, 'start']))
# one of both overlaps good
overlap = (overlap_1 | overlap_2) & ~nested
# identical chr? I didnt get that part. That may be different for your application
overlap &= df.loc[:, 'chr'] == ch
nested &= df.loc[:, 'chr'] == ch
# generate text
text = ''
# check if any nestings
if np.any(nested):
nested_indices = [*filter(lambda x: x[1], zip(range(len(nested)), nested))]
text = "I am nested within: "
region_names = []
for index, _ in nested_indices:
region_names.append(df.iloc[index,0])
text += ", ".join(region_names)+"; "
# check if any overlaps (obviously one can write that more DRY), since it repeats the pattern from above
if np.any(overlap):
overlap_indices = [*filter(lambda x: x[1], zip(range(len(overlap)), overlap))]
text += "I overlap: "
region_names = []
for index, _ in overlap_indices:
region_names.append(df.iloc[index,0])
text += ", ".join(region_names)
if text == '':
text = 'I am not nested nor do I overlap something'
overlaps_texts.append(text)
df.loc[:, 'overlap'] = overlaps_texts
print(df)
输出:
start ... overlap
0 1913 ... I am not nested nor do I overlap something
1 46430576 ... I am nested within: A; I overlap: G
2 52899183 ... I am nested within: A; I overlap: B, G
3 58456122 ... I am nested within: A, B, C; I overlap: E, F, G
4 62925929 ... I am nested within: A, B, C; I overlap: D, F, G
5 65313395 ... I am nested within: A, B, C; I overlap: D, E, G
6 65511483 ... I am nested within: A; I overlap: B, C, D, E, F
7 65957829 ... I am not nested nor do I overlap something