Python 迭代不同的数据帧,检查一个数据帧的元素是否存在于另一个数据帧中

Python 迭代不同的数据帧,检查一个数据帧的元素是否存在于另一个数据帧中,python,pandas,Python,Pandas,我有两个不相等的多行数据帧 df1=ft1_hyp: assembly non-redundant name 1 GCF_000401195.1 WP_016197566.1 F-type 3 GCF_000401195.2 xx_01 conjugative 7 GCF_000401195.4 yy_02 DUF1378 9 GCF_000401

我有两个不相等的多行数据帧 df1=ft1_hyp:

    assembly          non-redundant         name
1   GCF_000401195.1   WP_016197566.1        F-type
3   GCF_000401195.2   xx_01                 conjugative 
7   GCF_000401195.4   yy_02                 DUF1378
9   GCF_000401195.5   WP_004178060.1        HP1
15  GCF_000401195.7   zz_03                 HP3
df2=相同的硬件保护:

    query           subject         HPSame
0   WP_000031677.1  WP_000031706.1  HPS_1
1   xx_01           WP_001330846.1  HPS_2
2   WP_000339857.1  WP_032417926.1  HPS_3
3   WP_000339857.1  WP_032426627.1  HPS_4
4   WP_000376615.1  yy_02           HPS_5
5   WP_000376615.1  WP_000376617.1  HPS_6
6   WP_000376615.1  WP_004883563.1  HPS_7
7   zz_03           WP_103826461.1  HPS_8
我试图找出df1是否由df2的主题或查询present组成。如果存在,则在df1“new NAME”中创建一个新列,并将HPSame放入,否则放入NAME。 我想要的结果是, df1=

我试过了

hp_filtered = pd.DataFrame(columns[])

for a, b in same_hyp_prot.iterrows():
        for c, d in ft1_hyp.iterrows():
            if b[0] or b[1] == d[1]:
                hp_filtered = hp_filtered.append({'assembly': d[0], 'non_redundant_refseq': d[1], 'name': d[2], 'New name': [b[2]]}, ignore_index=True)
这花费了很多时间来完成,并尝试对其进行矢量化,并抛出ValueError:只能比较标签相同的系列对象

ft1_hyp.loc[(ft1_hyp['non-redundant'] == same_hyp_prot['query']) | (ft1_hyp['non-redundant'] == same_hyp_prot['subject']), 'NEW NAME'] = same_hyp_prot['HPSame']
ft1_hyp.loc[(ft1_hyp['non-redundant'] != same_hyp_prot['query']) & (ft1_hyp['non-redundant'] != same_hyp_prot['subject']), 'NEW NAME'] = ft1_hyp['name']
    
  • 您可以在每列上合并
    left
    两次,每次都将列重命名为
    非冗余
    ,以使合并干净
  • 然后,使用
    fillna
    组合三列(
    NEW NAME 1
    NEW NAME 2
    NAME
    ),并传递这些列。您必须确保将
    fillna(df3['name'])
    作为最后一个
    .fillna()

  • 这里使用
    .pop()
    有点花哨;因此,或者,您也可以对最后两行代码做一些更简单的理解:

    df3['NEW NAME'] = df3['NEW NAME 1'].fillna(df3['NEW NAME 2']).fillna(df3['name'])
    df3 = df3.drop(['NEW NAME 1', 'NEW NAME 2'], axis=1)
    

    基本上,使用
    .pop()
    可以在同一步骤中删除列和
    fillna()
    。或者,您可以将其包含在
    drop
    的下一行代码中,因为您必须删除另一列。

    谢谢David。非常感谢。
    df3 = (pd.merge(df1,df2[['query','HPSame']].rename({'query' : 'non-redundant','HPSame' : 'NEW NAME 1'}, axis=1),
                    how='left', on='non-redundant')
             .merge(df2[['subject','HPSame']].rename({'subject' : 'non-redundant','HPSame' : 'NEW NAME 2'}, axis=1),
                    how='left', on='non-redundant'))
    df3['NEW NAME'] = df3['NEW NAME 1'].fillna(df3.pop('NEW NAME 2')).fillna(df3['name'])
    df3 = df3.drop('NEW NAME 1', axis=1)
    df3
    Out[1]: 
              assembly   non-redundant         name NEW NAME
    0  GCF_000401195.1  WP_016197566.1       F-type   F-type
    1  GCF_000401195.2           xx_01  conjugative    HPS_2
    2  GCF_000401195.4           yy_02      DUF1378    HPS_5
    3  GCF_000401195.5  WP_004178060.1          HP1      HP1
    4  GCF_000401195.7           zz_03          HP3    HPS_8
    
    df3['NEW NAME'] = df3['NEW NAME 1'].fillna(df3['NEW NAME 2']).fillna(df3['name'])
    df3 = df3.drop(['NEW NAME 1', 'NEW NAME 2'], axis=1)