【问题标题】:Pandas: Compare a column to all other columns of a dataframe熊猫:将一列与数据框的所有其他列进行比较
【发布时间】:2017-01-31 12:24:40
【问题描述】:

我有一个场景,我有一个新主题正在测试一系列特征,结果都是字符串分类值。测试完成后,我需要将新数据集与所有受试者的主数据集进行比较,并寻找给定阈值保持(比如 90%)的相似性(匹配)。

因此,我需要能够对新数据集中的每个新主题与主数据集中的每一列以及新数据集中的其他列进行列式(主题)比较可能的最佳性能,因为生产数据集有大约 50 万列(并且还在增长)和 10,000 行。

下面是一些示例代码:

master = pd.DataFrame({'Characteristic':['C1', 'C2', 'C3'], 
                                   'S1':['AA','BB','AB'],
                                   'S2':['AB','-','BB'],
                                   'S3':['AA','AB','--']})
new = pd.DataFrame({'Characteristic':['C1', 'C2', 'C3'], 
                                'S4':['AA','BB','AA'],
                                'S5':['AB','-','BB']})
new_master = pd.merge(master, new, on='Characteristic', how='inner')  

def doComparison(comparison_df, new_columns, master_columns):
  summary_dict = {}
  row_cnt = comparison_df.shape[0]

  for new_col_idx, new_col in enumerate(new_columns):
      # don't compare the Characteristic column
      if new_col != 'Characteristic':
        print 'Evalating subject ' + new_col + ' for matches'
        summary_dict[new_col] = []
        new_data = comparison_df.ix[:, new_col]
        for master_col_idx, master_col in enumerate(master_columns):
            # don't compare same subject or Characteristic column
            if new_col != master_col and master_col != 'Characteristic':
                master_data = comparison_df.ix[:, master_col]
                is_same = (new_data == master_data) & (new_data != '--') & (master_data != '--')
                pct_same = sum(is_same) * 100 / row_cnt
                if pct_same > 90:
                    print '  Found potential match ' + master_col + ' ' + str(pct_same) + ' pct'
                    summary_dict[new_col].append({'match' : master_col, 'pct' : pct_same})
  return summary_dict

result = doComparison(new_master, new.columns, master.columns)

这种方式可行,但我想提高效率和性能,但不知道如何。

【问题讨论】:

    标签: python pandas dataframe analytics data-science


    【解决方案1】:

    另一种选择

    import numpy as np
    import pandas as pd
    from sklearn.utils.extmath import cartesian
    

    利用 sklearn 的笛卡尔函数

    col_combos = cartesian([ new.columns[1:], master.columns[1:]])
    print (col_combos)
    
    [['S4' 'S1']
     ['S4' 'S2']
     ['S4' 'S3']
     ['S5' 'S1']
     ['S5' 'S2']
     ['S5' 'S3']]
    

    为除特征之外的新列中的每一列创建一个带有键的字典。 请注意,这似乎是在浪费空间。也许只是保存匹配的那些?

    summary_dict = {c:[] for c in new.columns[1:]} #copied from @Parfait's answer
    

    Pandas/Numpy 可以轻松比较两个系列。
    示例;

    print (new_master['S4'] == new_master['S1'])
    
    0     True
    1     True
    2    False
    dtype: bool
    

    现在我们在 numpy 的 count_nonzero() 的帮助下遍历 Series 组合并计算 Trues。其余的与您所拥有的相似

    for combo in col_combos:
        match_count = np.count_nonzero(new_master[combo[0]] == new_master[combo[1]])
        pct_same = match_count * 100 / len(new_master)
        if pct_same > 90:
            summary_dict[combo[0]].append({'match' : combo[1], 'pct': match_count / len(new_master)})
    
    print (summary_dict)
    
    {'S4': [], 'S5': [{'pct': 1.0, 'match': 'S2'}]}
    

    我很想知道它的表现如何。祝你好运!

    【讨论】:

      【解决方案2】:

      考虑以下运行列表理解的调整,以构建两个数据框列名称的所有组合,然后迭代到> 90% 阈值匹配。

      # LIST COMPREHENSION (TUPLE PAIRS) LEAVES OUT CHARACTERISTIC (FIRST COL) AND SAME NAMED COLS
      columnpairs = [(i,j) for i in new.columns[1:] for j in master.columns[1:] if i != j]
      
      # DICTIONARY COMPREHENSION TO INITIALIZE DICT OBJ
      summary_dict = {col:[] for col in new.columns[1:]}
      
      for p in columnpairs:
          i, j = p
      
          is_same = (new['Characteristic'] == master['Characteristic']) & \
                    (new[i] == master[j]) & (new[i] != '--') & (master[j] != '--')
          pct_same = sum(is_same) * 100 / len(master)
      
          if pct_same > 90:        
              summary_dict[i].append({'match' : j, 'pct': pct_same})
      
      print(summary_dict)
      # {'S4': [], 'S5': [{'match': 'S2', 'pct': 100.0}]}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-20
        • 1970-01-01
        • 2019-09-11
        • 1970-01-01
        • 1970-01-01
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多