Pandas检查另一个数据帧中是否存在行并追加索引

时间:2016-09-19 21:09:06

标签: python pandas

我有一个问题要迭代我的数据帧。我正在做的事情是花费很多时间而且我没有那么多行(我有300k行)

我想做什么?

  1. 检查一个DF(A)是否包含另一个DF(B)的两列的值。您可以将其视为多重关键字段

  2. 如果为True,则获取DF.B的索引并分配给DF.A的一列

  3. 如果为False,则两步:

    一个。向DF.B追加未找到的两列

    湾将新ID分配给DF.A(我不能这样做)

  4. 这是我的代码,其中:

    1. df是DF.A而df_id是DF.B:

    2. SampleID和ParentID是我有兴趣检查它们是否存在于两个数据帧中的两列

    3. Real_ID是我想要分配DF.B(df_id)的id的列

      for index, row in df.iterrows():
          #check if columns exist in the other dataframe
          real_id = df_id[(df_id['SampleID'] == row['SampleID']) & (df_id['ParentID'] == row['ParentID'])]
      
          if real_id.empty:
              #row does not exist, append to df_id
              df_id = df_id.append(row[['SampleID','ParentID']])
          else:
              #row exists, assign id of df_id to df
              row['Real_ID'] = real_id.index
      
    4. 实施例

      DF.A(df)

         Real_ID   SampleID   ParentID  Something AnotherThing
      0             20          21          a          b      
      1             10          11          a          b      
      2             40          51          a          b       
      

      DF.B(df_id)

         SampleID   ParentID  
      0    10          11         
      1    20          21     
      

      结果

         Real_ID   SampleID   ParentID  Something AnotherThing
      0      1      10          11          a          b      
      1      0      20          21          a          b      
      2      2      40          51          a          b      
      
      
         SampleID   ParentID  
      0    20          21         
      1    10          11    
      2    40          51
      

      同样,这个解决方案非常慢。我确定有更好的方法可以做到这一点,这就是我在这里问的原因。不幸的是,这是我几个小时后得到的......

      由于

1 个答案:

答案 0 :(得分:6)

你可以这样做:

数据(注意B DF中的索引):

In [276]: cols = ['SampleID', 'ParentID']

In [277]: A
Out[277]:
   Real_ID  SampleID  ParentID Something AnotherThing
0      NaN        10        11         a            b
1      NaN        20        21         a            b
2      NaN        40        51         a            b

In [278]: B
Out[278]:
   SampleID  ParentID
3        10        11
5        20        21

<强>解决方案:

In [279]: merged = pd.merge(A[cols], B, on=cols, how='outer', indicator=True)

In [280]: merged
Out[280]:
   SampleID  ParentID     _merge
0        10        11       both
1        20        21       both
2        40        51  left_only


In [281]: B = pd.concat([B, merged.ix[merged._merge=='left_only', cols]])

In [282]: B
Out[282]:
   SampleID  ParentID
3        10        11
5        20        21
2        40        51

In [285]: A['Real_ID'] = pd.merge(A[cols], B.reset_index(), on=cols)['index']

In [286]: A
Out[286]:
   Real_ID  SampleID  ParentID Something AnotherThing
0        3        10        11         a            b
1        5        20        21         a            b
2        2        40        51         a            b