根据多个行条件比较两个不同的数据帧

时间:2020-07-13 16:07:20

标签: python pandas dataframe merge

我有两个数据框,其中包含有关同一患者的不同信息。我需要使用数据框1来过滤数据框2,以便数据框2仅在df_1chromosome,{ {1}}和strand。如果df_1中有一个elementloc值,我想将patient放在同一位置的NaN中。对于NaN中已有的df_2个值,我想将其保留为NaN。

因此,NaNdf_2像这样:

df_1

我希望新的df_2看起来像:

df_1 = pd.DataFrame({'chromosome': [1, 1, 5, 4],
                     'strand': ['-', '-', '+', '-'],
                     'elementloc': [4991, 8870, 2703, 9674],
                     'Patient1_Reads': ['NaN', 25, 50, 'NaN'],
                     'Patient2_Reads': [35, 200, 'NaN', 500]})

print(df_1)                                                                    
   chromosome strand  elementloc Patient1_Reads Patient2_Reads
0           1      -        4991            NaN             35
1           1      -        8870             25            200
2           5      +        2703             50            NaN
3           4      -        9674            NaN            500


df_2 = pd.DataFrame({'chromosome': [1, 1, 5, 4],
                     'strand': ['-', '-', '+', '-'],
                     'elementloc': [4991, 8870, 2703, 9674],
                     'Patient1_PSI': [0.76, 0.35, 0.04, 'NaN'],
                     'Patient2_PSI': [0.89, 0.15, 0.47, 0.32]})
print(df_2)                                                                      
   chromosome strand  elementloc   Patient1_PSI    Patient2_PSI
0           1      -        4991           0.76            0.89
1           1      -        8870           0.35            0.15
2           5      +        2703           0.04            0.47
3           4      -        9674            NaN            0.32

1 个答案:

答案 0 :(得分:2)

使用:

df3 = df1.merge(df2, on=['chromosome', 'strand', 'elementloc'])

r_cols = df3.columns[df3.columns.str.endswith('_Reads')]
p_cols = r_cols.str.strip('Reads') + 'PSI'

df3[p_cols] = df3[p_cols].mask(df3[r_cols].isna().to_numpy())
df3 = df3.drop(r_cols, 1)

详细信息:

步骤A:使用DataFrame.merge创建通过合并df3上的数据帧df1df2获得的合并数据帧['chromosome', 'strand', 'elementloc']

# print(df3)
   chromosome strand  elementloc  Patient1_Reads  Patient2_Reads  Patient1_PSI  Patient2_PSI
0           1      -        4991             NaN            35.0          0.76          0.89
1           1      -        8870            25.0           200.0          0.35          0.15
2           5      +        2703            50.0             NaN          0.04          0.47
3           4      -        9674             NaN           500.0           NaN          0.32

步骤B:使用.str.endswith来获取df3结尾的_Reads中的列,我们将其称为r_cols列,然后使用此_Reads列来获得相应的_PSI列,我们将其称为p_cols列。

# print(r_cols)
Index(['Patient1_Reads', 'Patient2_Reads'], dtype='object')

# print(p_cols)
Index(['Patient1_PSI', 'Patient2_PSI'], dtype='object')

步骤C:在_Reads列上使用DataFrame.isna获得布尔掩码,然后将此掩码与DataFrame.mask一起使用以填充相应的{{ NaN列中的1}}值。最后,使用DataFrame.drop从合并的datframe _PSI中删除_Reads列以获得所需的结果:

df3