2016-09-22 6 views
3

の他のすべての列に列を比較私は結果がすべての文字列カテゴリ値です特徴のシリーズのためにテストされている新しい科目を持ってシナリオを持っています。テストが完了したら、私はすべての被験者のマスターデータセットに新しいデータセットを比較し、与えられたスレッシュホールド(例えば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) 

この方法で動作しますが、私は効率性とパフォーマンスを向上したいと正確にどのように知りません。

答えて

0

は、> 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}]} 
1

別のオプション

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

col_combos = cartesian([ new.columns[1:], master.columns[1:]]) 
print (col_combos) 

[['S4' 'S1'] 
['S4' 'S2'] 
['S4' 'S3'] 
['S5' 'S1'] 
['S5' 'S2'] 
['S5' 'S3']] 

特性を除いて、新しい内のすべての列のキーを持つ辞書の作成sklearnのデカルト機能を活用します。 注、これはスペースの無駄のように思えます。たぶん、一致するものを保存するだけですか?

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

パンダス/ナンシーは2つのシリーズを比較しやすくします。
例。

print (new_master['S4'] == new_master['S1']) 

0  True 
1  True 
2 False 
dtype: bool 

そして今、我々は)(シリーズコンボを通して反復処理し、numpyののcount_nonzeroの助けを借りて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'}]} 

私はそれがどのように実行するか知りたいと思います。がんばろう!