我有一个表(程序的简化输出),需要过滤:
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启动
import pandas
df = pandas.read_csv("table", sep='\s+', names=["id", "hit", "from", "to", "value"])
df.sort_values(['from', "value"]).groupby('id')但是,如何检查重叠(from到to) &删除得分较高的重叠?
这是我的预期输出:
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有两个相同值的重叠命中,因此这两个条目都将被踢出。
发布于 2019-04-20 09:53:52
首先,我们介绍了一个惟一的ID并使用了pd.Interval。
df['ID'] = range(df.shape[0])
df['Interval'] = df.apply(lambda x: pd.Interval(x['from'], x['to'], closed='both'), axis=1)在此之后,我们将自己加入df并计算重叠部分:
columns = ['id', 'Interval', 'ID']
connected = df[columns].merge(df[columns], on='id')
connected['Overlap'] = connected.apply(lambda x: x['Interval_x'].overlaps(x['Interval_y']), axis=1)
connected = connected.loc[connected['Overlap'] == True, ['id', 'ID_x', 'ID_y']]现在我们知道哪些ID是重叠的,但是我们不知道哪个ID构建了一个连接的组件。一般来说,这不能通过简单的算法来完成,比如重划,但是一点图论会有所帮助。所以我们建立了一个图
graph = connected.groupby(['id', 'ID_x']).agg(list)
并通过深度优先搜索计算连接部件。
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发布于 2019-04-16 11:17:12
如果您不介意代码中的多行代码,那么这样的代码应该可以工作,我想.(这里是python新手.) 来源
df.sort_values(['from', "value"]).groupby('id')
df.drop_duplicates(subset=['id', 'value'], keep=False, inplace=True)参数设置为false,因为您根本不想要重复的行。
,其结果是:
id hit from to value
0 A hit1 56 102 0.00085
3 C hit4 332 480 3.40E-15
4 D hit5 291 512 3.80E-24
9 D hit10 514 600 0.0021和要摆脱混乱的索引列:
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.0021PS:这是我第一次给出答案,所以请温柔一点。而且我还在学英语。
发布于 2019-04-16 20:53:05
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”值进行排序,并检查next“from”值是否小于“to”值。np.inf只需确保第一个值在分组中始终为0。
然后,我们在df中将掩码设置为自己的列。然后,我们按所需的一切进行分组,删除任何副本,重新设置索引,然后最后删除掩码。
https://stackoverflow.com/questions/54969074
复制相似问题