

Big queryのテーブルにあるテキストを比較し最も近いもの同士をマッチさせて  
CSVで出力したいと考えています。

Big queryの知識とdifflibに関する知識が浅いため、Pythonに詳しい方がいましたら  
教えていただけますと幸いです。以下が試したことになります。

**1．Big queryにテーブルstringsA, strinsBを2つ作成**

stringsA

id | name | title | description | latitude | longtitude  
---|---|---|---|---|---  
1 | たか歯科 | null | null | 35.1636963 | 136.884171  
2 | ホワイトニングクリニックtanaka | null | null | 35.1704369 | 136.879532  
3 | aaaaaaaaaaaaaaa | null | null | 37.952049 | 139.113178  
  
stringsB

id | name | title | description | latitude | longtitude  
---|---|---|---|---|---  
1 | たか歯科 品川院 | null | null | 35.1636963 | 136.884171  
2 | ホワイトニングクリニック Tanaka | null | null | 35.1704369 | 136.879532  
3 | bbbbbbbbb | null | null | 37.94230 | 139.12345  
  
**2．テーブルstringsAのB列にあるnameを、stringsBのB列にあるnameと比較**  
**3\. stringsAにあるテキストに最も近いstringsBの文字列をCSVで出力**  
出力されるCSVのイメージはこちら

stringsA | stringsB | similarity  
---|---|---  
たか歯科 | たか歯科 品川院 | 0.4166666667  
ホワイトニングクリニックtanaka | ホワイトニングクリニック Tanaka | 0.9189189189  
aaaaaaaaaaaaaaa |  | 0  
  
以上を実現するために下記のようなコードを書きました。

[code]

    from google.cloud import bigquery
    from google.oauth2 import service_account
    from difflib import get_close_matches, SequenceMatcher
    import csv
    key_path = 'KEY_PATH'
    credentials =  service_account.Credentials.from_service_account_file(
        key_path,
        scopes=["https://www.googleapis.com/auth/cloud-platform"], #https://developers.google.com/identity/protocols/oauth2/scopes
    )
    
    
    stringsA = ('''
    SELECT　*　FROM `stringsA`
    ''')
    
    stringsB = ('''
    SELECT　*　FROM `stringsB`
    ''')
    
    
    client = bigquery.Client(
        credentials=credentials,
        project=credentials.project_id,
    )
    query_job = client.query(stringsA)
    rows = query_job.result()
    
    #### リスト b から一番類似している文字列を抽出し、
    #### その類似度を取得し、それらをリストとして返す関数を定義。
    #### 類似度の足切り率はデフォルトを最低にして、変更出来るようにしておく
    def closest(x, rate=0.01):
        result = get_close_matches(x, stringsB, n=1, cutoff=rate)
        if len(result) <= 0:
            return [x, None, 0.0]
        result = result[0]
        s = SequenceMatcher(None, x, result)
        return [x, result, s.ratio()]
    
    #### リスト a のデータ全てを順番に処理するリスト内包表記
    data = [closest(s) for s in stringsA]
    
    #### csvファイルとして出力(encoding等は必要に応じて変更)
    with open('closest02.csv', 'w', newline='', encoding='UTF-8') as f:
        csvwriter = csv.writer(f)
        csvwriter.writerow(['stringsA','stringsB','類似度'])
        csvwriter.writerows(data)
    
    
    
[/code]

ただ、出力されるCSVは以下のようになってしまい  
想定している結果になりません。

stringsA | stringsB | 類似度  
---|---|---  
|  | 1  
S |  | 0  
E |  | 0  
L |  | 0  
E |  | 0  
  
少し長くわかりずらいかもしれません。  
以上となりますが、情報不足等ありましたら申し訳ございません。  
その際はご指摘していただけますと幸いです。


CC BY-SA 4.0
2022-08-03T03:39:51.077
90357
2022-08-03T04:03:21.300
2022-08-03T04:03:21.300
3060
52109
question
python pandas google-bigquery
Big queryの2つのテーブルにあるテキストを比較→最も近いテキストをCSV形式で出力したい