Python3:删除选项卡中的重叠

2024-09-28 03:25:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个表格(程序的简化输出),我需要过滤:

id   hit from   to value
A   hit1    56  102 0.00085
B   hit2    89  275 0.00034
B   hit3    240 349 0.00034
C   hit4    332 480 3.40E-15
D   hit5    291 512 3.80E-24
D   hit6    287 313 0.00098
D   hit7    381 426 0.00098
D   hit8    287 316 0.0029
D   hit9    373 422 0.0029
D   hit10   514 600 0.0021

对于每个id,df应该按from排序,如果有重叠的命中,则保留value下面的那个。在

到目前为止,这是我的代码,它首先以from开头,然后以value开头:

^{pr2}$

但是,我如何检查重叠(fromto)&删除得分较高的那一个?在

这是我的预期输出:

id   hit from   to valu
A   hit1    56  102 0.00085
C   hit4    332 480 3.40E-15
D   hit5    291 512 3.80E-24
D   hit10   514 600 0.0021

请注意,id B有两个相同值的重叠命中,因此这两个条目都将被踢出。在


Tags: tofrom程序idvalue表格hithit1
3条回答

首先,我们引入一个唯一的ID,并使用^{}

df['ID'] = range(df.shape[0])
df['Interval'] = df.apply(lambda x: pd.Interval(x['from'], x['to'], closed='both'), axis=1)

在此之后,我们将df与自身结合并计算重叠部分:

^{pr2}$

现在我们知道哪些id重叠,但不知道哪个id构建了一个连接的组件。一般来说,这不能通过像重新排序这样的简单算法来完成,但是位graph theory有帮助。所以我们建立了一个图

graph = connected.groupby(['id', 'ID_x']).agg(list)

通过depth first search计算连通分量

def connections(graph, id):
    def dict_to_df(d):
        df = pd.DataFrame(data=[d.keys(), d.values()], index=['ID', 'Subgraph']).T
        df['id'] = id
        return df[['id', 'Subgraph', 'ID']]

    def dfs(node, num):
        visited[node] = num
        for _node in graph.loc[node].iloc[0]:
            if _node not in visited:
                dfs(_node, num)

    visited = {}
    graph = graph.loc[id]
    for (num, node) in enumerate(graph.index):
        if node not in visited:
            dfs(node, num)

    return dict_to_df(visited)

dfs = []
for id in graph.index.get_level_values(0).unique():
    dfs.append(connections(graph, id))

conns = pd.concat(dfs)

conns包含连接的组件,我们可以将它们组合在一起:

data = df.merge(conns[['Subgraph', 'ID']], on=['ID'])

最后一个任务是选择要保留的行:

def select_min(x):
    m = x['value'].min()
    if len(x) > 1 and (x['value'] == m).all():
        return -1
    else:
        return x['value'].idxmin()

selected = data.groupby(['id', 'Subgraph'])['value', 'ID'].apply(select_min)
selected = selected[selected >= 0]

现在我们完成了:

print(df.loc[df.ID.isin(selected), :].drop(columns=['ID', 'Interval']))
  id    hit  from   to         value
0  A   hit1    56  102  8.500000e-04
3  C   hit4   332  480  3.400000e-15
4  D   hit5   291  512  3.800000e-24
9  D  hit10   514  600  2.100000e-03

如果你不介意在你的代码中有多行代码,我想这样的方法应该行得通。。。(这里是python新手…source

df.sort_values(['from', "value"]).groupby('id')
df.drop_duplicates(subset=['id', 'value'], keep=False, inplace=True)

keep”参数设置为false,因为您根本不需要重复的行。在

结果是:

^{pr2}$

并且要删除混乱的索引列:

df.reset_index(drop=True, inplace=True)

结果是:

  id    hit from   to     value
0  A   hit1   56  102   0.00085
1  C   hit4  332  480  3.40E-15
2  D   hit5  291  512  3.80E-24
3  D  hit10  514  600    0.0021

附言:这是我第一次回答,所以,请温柔一点。而且,我还在学英语。在

df = pd.DataFrame({'id': ['A', 'B', 'B', 'C', 'D', 'D' ,'D', 'D', 'D', 'D', 'D'],
                  'hit': ['hit1', 'hit2', 'hit3','hit4', 'hit5','hit6', 'hit7','hit8', 'hit9','hit10', 'hit11'],
                  'from': [56,89,240,332,291,287,381,287,373,514, 599],
                  'to':[102,275,349,480,512,313,426,316,422,600, 602],
                  'value': [0.00085,0.00034,0.00034,3.40E-15,3.80E-24,0.00098,0.00098,0.0029,0.0029,0.0021, 0.002]})

overlapMask =  df.sort_values(by = 'from')\
                 .groupby('id')\
                 .apply(lambda x: np.where(x['from'] < x['to'].shift(), 0 , 1).cumsum())\
                 .reset_index()

df['Mask'] = np.concatenate((overlapMask[0].values))


df.drop_duplicates(subset = ['id','value'], keep = False, inplace = True)


df.sort_values(by = 'value')\
  .groupby(['id', 'Mask'])\
  .head(1)\
  .reset_index()\
  .drop(['Mask', 'index'],axis = 1)\
  .sort_values(by = 'id')


    id  hit    from  to    value
2   A   hit1    56  102 8.500000e-04
1   C   hit4    332 480 3.400000e-15
0   D   hit5    291 512 3.800000e-24
3   D   hit11   599 602 2.000000e-03

所以我的解决方案是用一个掩模来检查重叠。通过对“from”值进行排序,并检查下一个“from”值是否小于上一个“to”值。这个np.inf公司只需确保分组中的第一个值始终为0。在

然后我们在df中把这个面具列为自己的列。然后我们根据需要进行分组,删除所有重复项,重置索引,最后删除掩码。在

相关问题 更多 >

    热门问题