【问题标题】:dataframe manipulation python based on conditons基于条件的数据框操作python
【发布时间】:2021-03-09 11:25:23
【问题描述】:
input_df1:  ID       MSG         
            id-1    'msg1'                     
            id-2    'msg2'                     
            id-3    'msg3'


ref_df2:     ID       MSG
             id-1     'msg1'
             id-2     'xyzz'
             id-4     'msg4'

我正在尝试根据以下条件生成输出数据帧:

  1. 如果 input_df 中的 'id' 和 'msg' 值都与 ref_df 中的值匹配 = 匹配

  2. 如果 input_df 中的 'id' 值在 ref_df 中不存在 = notfound

  3. 如果只有 input_df 中的 'id' 值与 ref_df 中的 'id' 值匹配 = not_matched

sample output:  ID       MSG    flag
                id-1    'msg1'  matched 
                id-2    'msg2'  not_matched
                id-3    'msg3'  notfound

我可以使用列表来做到这一点,但考虑到我要处理大量数据这一事实,性能很重要,因此我正在寻找一种更快的解决方案。 任何一点帮助将不胜感激 '''

【问题讨论】:

    标签: python-3.x pandas list dataframe data-manipulation


    【解决方案1】:

    让我们使用map 将id 映射到参考消息并使用np.select

    ref_msg = df1['ID'].map(df2.set_index('ID')['MSG'])
    
    df1['flag'] = np.select((ref_msg.isna(), ref_msg==df1['MSG']),
                            ('not found', 'matched'), 'not_matched')
    

    输出(df1):

         ID     MSG         flag
    0  id-1  'msg1'      matched
    1  id-2  'msg2'  not_matched
    2  id-3  'msg3'    not found
    

    【讨论】:

    • @BEN_YO 感恩节快乐。我的感恩节是一个月前 :-)。
    【解决方案2】:

    你也可以使用df.mergeindicator=True参数:

    In [3867]: x = df1.merge(df2, how='outer', indicator=True).groupby('ID', as_index=False).last()
    
    In [3864]: d = {'both':'matched', 'right_only':'not_matched', 'left_only':'notfound'}
    
    In [3869]: x._merge = x._merge.map(d)
    
    In [3871]: x
    Out[3871]: 
         ID     MSG       _merge
    0  id-1  'msg1'      matched
    1  id-2  'xyzz'  not_matched
    2  id-3  'msg3'     notfound
    

    【讨论】:

      【解决方案3】:

      最快最 Pythonic 的方式是使用字典,如下所示:

      list_ID_in = ['id-1', 'id-2', 'id-3']
      list_msg_in = ['msg1', 'msg2', 'msg3']
      
      list_ID_ref = ['id-1', 'id-2', 'id-4']
      list_msg_ref = ['msg1', 'xyzz', 'msg4']
      
      dict_in = {k:v for (k, v) in zip(list_ID_in, list_msg_in)}
      dict_ref = {k:v for (k, v) in zip(list_ID_ref, list_msg_ref)}
      
      list_out = [None] * len(dict_in)
      for idx, key in enumerate(dict_in.keys()):
          try:
              ref_value = dict_ref[key]
              if ref_value == dict_in[key]:
                  list_out[idx] = 'matched'
              else:
                  list_out[idx] = 'not_matched'
          except KeyError:
              list_out[idx] = 'not_found'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-02
        • 1970-01-01
        • 2019-03-23
        • 1970-01-01
        • 2015-04-15
        • 2020-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多