首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有趣的Pandas dataframe问题:如何在两列上删除重复(反向)--对于每个具有公共属性的行?

有趣的Pandas dataframe问题:如何在两列上删除重复(反向)--对于每个具有公共属性的行?
EN

Stack Overflow用户
提问于 2021-08-22 13:13:43
回答 2查看 194关注 0票数 0

在筛选出反复制后,我必须计算出实际重复的数量。下面是我的(工作示例)代码,但是对于90行000+来说太慢了。使用迭代:

代码语言:javascript
复制
import pandas as pd

data = {'id_x':[1,2,3,4,5,6],      
'ADDICTOID_x':['BFO:0000023', 'MF:0000016', 'BFO:0000023', 'MF:0000016', 'MF:0000016', 'ADDICTO:0000872'],     
'PMID':[34116904, 34116904, 34112174, 34112174, 34112174, 22429780],                  
'LABEL_x':['role', 'human being', 'role', 'human being', 'human being', 'FDA'],   
'id_y':[11,12,13,14,15,16],    
'ADDICTOID_y':['MF:0000016', 'BFO:0000023', 'MF:0000016', 'BFO:0000023', 'BFO:0000023', 'ADDICTO:0000904'],                
'LABEL_y':['human being', 'role', 'human being', 'role', 'role', '']}
dcp = pd.DataFrame(data)

dcp = dcp.drop(dcp[dcp.LABEL_x == dcp.LABEL_y].index)

for index, row in dcp.iterrows():  # THIS IS SLOW
        if ((dcp['ADDICTOID_x'] == row['ADDICTOID_y'])
            & (dcp['ADDICTOID_y'] == row['ADDICTOID_x'])
            & (dcp['PMID'] == row['PMID'])).any():  # Does the inverse of this row exist in the table?
            dcp.drop(index, inplace=True)

print("dcp after drop: ")
print(dcp)

我不能只使用dcp.duplicated(subset=['ADDICTOID_x', 'ADDICTOID_y'], keep='first'),因为它删除了所有的重复(有很多),我只想一个一个地做,并且'PMID‘也需要匹配。类似地,(dcp.ADDICTOID_x + dcp.ADDICTOID_y).isin(dcp.ADDICTOID_y + dcp.ADDICTOID_x) & (dcp.PMID == dcp.PMID)到处查找带有重复项的行。Iterrow和逐个测试是我找到的唯一可行的方法,但它太慢了。有人知道解决这个问题的办法吗?

在对反向重复进行过滤之后,我计算如下:data_chord_plot = dcp.groupby(['LABEL_x', 'LABEL_y'], as_index=False)[['PMID']].count() data_chord_plot.columns = ['source','target','value']

编辑:在这个简单的例子中,第1行和第3行被删除,因为它们是行2和4的反向重复。

编辑:我需要消除两列上有反向重复的行的“镜像”映像,但是对于每一行只有一个重复。有些行没有镜像。

正确输出(慢)示例:

id_x ADDICTOID_x PMID LABEL_x id_y ADDICTOID_y LABEL_y

12 MF:0000016 34116904人12 BFO:0000023

34 MF:0000016 34112174人14 BFO:0000023角色

4 5 MF:0000016 34112174人15 BFO:0000023角色

6 ADDICTO:0000872 22429780 FDA 16 ADDICTO:0000904

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-22 13:48:12

创建ADDICTOID_xy的排序元组,并使用drop_duplicates和正确的子集:

代码语言:javascript
复制
dcp['ADDICTOID'] = dcp[['ADDICTOID_x', 'ADDICTOID_y']].apply(sorted, axis=1) \
                                                      .apply(tuple)

out = dcp.drop_duplicates(subset=['ADDICTOID', 'PMID'], keep='first')
代码语言:javascript
复制
>>> out
   id_x      ADDICTOID_x      PMID LABEL_x  id_y      ADDICTOID_y      LABEL_y                           ADDICTOID
0     1      BFO:0000023  34116904    role    11       MF:0000016  human being           (BFO:0000023, MF:0000016)
2     3      BFO:0000023  34112174    role    13       MF:0000016  human being           (BFO:0000023, MF:0000016)
5     6  ADDICTO:0000872  22429780     FDA    16  ADDICTO:0000904               (ADDICTO:0000872, ADDICTO:0000904)
票数 0
EN

Stack Overflow用户

发布于 2021-08-22 13:42:29

也许有一种更短的方法,但我可以考虑将df与其反转的自身合并,然后只留下行,而不需要先前的匹配。因此,不要执行循环,而是:

代码语言:javascript
复制
dcp = dcp.merge(dcp[['id_x', 'PMID', 'ADDICTOID_x', 'ADDICTOID_y']].rename({'id_x': 'inv_id', 'ADDICTOID_x': 'inv_y', 'ADDICTOID_y': 'inv_x'}, axis=1), how='left')
dcp['was'] = (dcp['ADDICTOID_x'] == dcp['inv_x']) & (dcp['ADDICTOID_y'] == dcp['inv_y']) & (dcp['id_x'] > dcp['inv_id'])
dcp = dcp.sort_values(['id_x', 'was']).drop_duplicates('id_x', keep='last')
dcp = dcp.loc[~dcp['was'], 'id_x': 'LABEL_y']
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68881666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档