【问题标题】:Pandas check if row exist in another dataframe and append index熊猫检查行是否存在于另一个数据框中并附加索引
【发布时间】:2017-01-27 16:08:32
【问题描述】:

我在迭代我的数据框时遇到了一个问题。我正在做的方式是花费很长时间,而且我没有那么多行(我有 300k 行)

我想做什么?

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

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

  3. 如果为False,分两步:

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

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

这是我的代码,其中:

  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
    

示例:

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

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

谢谢

【问题讨论】:

  • 你能发布一些可重现的样本数据集和所需的输出数据集吗?
  • 我添加了一个示例来展示数据的组织方式以及预期的结果。我希望它现在更有意义
  • 你能解释一下你是怎么在最后一行得到Real_ID == 2的吗?
  • 我从 df_id (DF.B) 的索引中得到。我得到了 SampleID.A == SampleID.B && ParentID.A == ParentID.B 的索引。我更改了顺序,以便于阅读
  • 原始DF.B 中没有这样的索引值 - 这就是我要问的原因......

标签: python pandas


【解决方案1】:

你可以这样做:

数据(注意BDF中的索引):

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

【讨论】:

  • 如果我添加A['Real_ID'] = A[A[cols]==merged[cols]].index 会正确吗?似乎它在这里工作,但我只是想确保语法是否正确。
  • 谢谢。我之前尝试使用此合并功能但没有成功。您的代码运行速度超快!
  • @MarcusRenno,很高兴我能帮上忙 :)
猜你喜欢
  • 2018-07-01
  • 2014-06-26
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2018-01-28
相关资源
最近更新 更多