2

ID と NAME の 2 つの列を持つ account というテーブルがあります。ID は一意のハッシュですが、NAME は重複する可能性のある文字列です。

このExcelファイルを読み取り、0〜3個の同様のNAME値に一致するPythonスクリプトを作成しようとしていますが、うまく動作しないようです。誰か助けてくれませんか?ありがとう

import pandas as pd
from fuzzywuzzy import fuzz
import difflib

def get_spr(row):
    d = name1.apply(lambda x: (fuzz.ratio(x['NAME'], row['NAME']) * 0 if row['ID'] == x['ID'] else 1), axis=1)
    d = d[d>= 60]
    if len(d) == 0:
        v = ['']*2
    else:
        v = name1.ix[d.idxmax(),['ID' , 'NAME']].values
    return pd.Series(v, index=['ID', 'NAME'])


def score(tablerow):
    d = name1.apply(lambda x: fuzz.ratio(x['NAME'],tablerow['NAME']) * (0 if x['ID']==tablerow['ID'] else 1), axis=1)
    d = d[d>90]
    if len(d) == 0:
        v = [''] * 2
    else:
        v = name1.ix[d.order(ascending=False).head(3).index, ['ID' , 'NAME']].values
    return pd.DataFrame(v, index=['ID', 'NAME'])

account = "account_test.xlsx"

xl_acc1 = pd.ExcelFile(account)
xl_acc2 = pd.ExcelFile(account)

acc1 = xl_acc1.parse(xl_acc1.sheet_names[0])
acc2 = xl_acc2.parse(xl_acc2.sheet_names[0])

name1 = acc1[pd.notnull(acc1['NAME'])]
name2 = acc2[pd.notnull(acc2['NAME'])]
print 'Doing Fuzzy Matching'


name2= pd.concat((name2,name2.apply(get_spr, axis=1)), axis=1)
name2.to_excel(pd.ExcelWriter('res.xlsx'),'acc')

どんな助けでも大歓迎です!

ファイルには次のような行があります:-

ID                    NAME
0016F00001c7GDZQA2  Daniela Abriani
0016F00001c7GPnQAM  Daniel Abriani
0016F00001c7JRrQAM  Nisha Well
0016F00001c7Jv8QAE  Katherine
0016F00001c7cXiQAI  Katerine
0016F00001c7dA3QAI  Katherin
0016F00001c7kHyQAI  Nursing and Midwifery Council Research Office
0016F00001c8G8OQAU  Nisa Well

予想される(出力データフレーム)は次のようになります。

      ID               NAME          ID2          NAME2
    <hash1>          katherine      <hash2>       katerine
    <hash1>          katherine      <hash3>       katherin
    <hash4>          Nisa Well      <hash5>       Nisha Well

問題: 上記のコードは、一致するものを実際に連結せずに、出力保存ファイルとして入力を再現するだけです。

4

1 に答える 1

1

パンダでこれを行う必要はないと思います。これが私のずさんな解決策ですが、辞書を使用して目的の出力を取得します。

from fuzzywuzzy import process
df = pd.DataFrame([
                ['0016F00001c7GDZQA2',  'Daniela Abriani'],
                ['0016F00001c7GPnQAM',  'Daniel Abriani'],
                ['0016F00001c7JRrQAM',  'Nisha Well'],
                ['0016F00001c7Jv8QAE', 'Katherine'],
                ['0016F00001c7cXiQAI', 'Katerine'],
                ['0016F00001c7dA3QAI',  'Katherin'],
                ['0016F00001c7kHyQAI',  'Nursing and Midwifery Council Research Office'],
                ['0016F00001c8G8OQAU',  'Nisa Well']], 
                columns=['ID', 'NAME'])

一意のハッシュを辞書に取得します。

hashdict = dict(zip(df['ID'], df['NAME']))

関数を定義しますcheckpair。相互ハッシュペアを削除するために必要になります。このメソッドは と を追加(hash1, hash2)(hash2, hash1)ますが、これらのペアの 1 つだけを保持したいと思います。

def checkpair (a,b,l):
    for x in l:
        if (a,b) == (x[2],x[0]):
            l.remove(x)

hashdict.items()ここで、途中で上位 3 つの一致を見つけることを繰り返します。fuzzywuzzy docsにメソッドの詳細が記載されていprocessます。

matches = []
for k,v in hashdict.items():

    #see docs for extract -- 4 because you are comparing a name to itself
    top3 = process.extract(v, hashdict, limit=4)

    #remove the hashID compared to itself
    for h in top3:
        if k == h[2]:
            top3.remove(h)

    #append tuples to the list "matches" if it meets a score criteria      
    [matches.append((k, v, x[2], x[0], x[1])) for x in top3 if x[1] > 60] #change score?

    #remove reciprocal pairs
    [checkpair(m[0], m[2], matches) for m in matches]

df = pd.DataFrame(matches, columns=['id1', 'name1', 'id2', 'name2', 'score'])
# write to file
writer = pd.ExcelWriter('/path/to/your/file.xlsx')
df.to_excel(writer,'Sheet1')
writer.save()

出力:

    id1     name1   id2     name2   score
0   0016F00001c7JRrQAM  Nisha Well  0016F00001c8G8OQAU  Nisa Well   95
1   0016F00001c7GPnQAM  Daniel Abriani  0016F00001c7GDZQA2  Daniela Abriani     97
2   0016F00001c7Jv8QAE  Katherine   0016F00001c7dA3QAI  Katherin    94
3   0016F00001c7Jv8QAE  Katherine   0016F00001c7cXiQAI  Katerine    94
4   0016F00001c7dA3QAI  Katherin    0016F00001c7cXiQAI  Katerine    88
于 2016-03-14T13:27:38.917 に答える