EXCEL内のデータの重複、差分を取ろう②

投稿者: | 2021年5月21日

前回の記事ではエクセル内の1行分のデータの重複を除外してデータを取得する方法を紹介しました。
今回はより実用的な複数行のデータの集合演算(重複、差分、和集合)の取得について説明します。

私は特許調査や分析を生業としています。仕事をしていてよく生じる問題として、2つの特許公報データの差分を知りたいということがあります。例えば特許調査済みの集合がリストですでにあるとして、追加で調査集合を作成した場合にその差分を知りたいということがよくあります。

処理対象データ

それでは早速データを使って処理しながら説明します。データは前回の「ゴルフデータ全件.xls」をもとに作成した処理用データを使用します。この中から抽出した公報番号をA列、A列とは別の公報番号をB列に記載したデータを作成しました。以下から取得してください。

具体的には以下の内容となります。

データの読み込み

エクセルファイルの読み込みは前回と同様に行います。

# openpyxl がインストールされていない方は以下を実行(コメントアウトを外す)
# pip install openpyxl

import openpyxl

# エクセルファイルのパス(置き場所)を指定します。自身の環境に合わせてください。
workbook = openpyxl.load_workbook(r'C:\python_ip\20210522\pubnumber_list.xlsx')

# 先頭のシートを取得
worksheet = workbook.worksheets[0]

次にA列、B列のデータをリストに読み込みます。各列の読み込みを前回と同様にして列ごとに繰り返すことで実現できます。各列で同じ処理になるので関数化して取得するようにします。
関数get_coldataで該当行の列データを取得し、その後タイトル行(エクセル内の1行目であり、リストでの0番目のデータである「A列」および「B列」)を除外しています。

# 指定列('A', 'B', ... etc.)のデータを取得する関数の宣言
# 空白行はないことを前提とする
def get_coldata(col):
    # 入力された最終行を取得
    max_row =worksheet.max_row

    # データのセルを取得
    cells = worksheet[col+'1':col+str(max_row)]
    
    # 関数の返り値のリストを用意
    data = []

    for c in cells:
        if c[0].value is not None: #データの存在をチェック None(空白)でない
            data.append(c[0].value) #セルの値を順次追加
    
    return data
## ここまでが関数 get_coldata


# 上記の関数でデータを取得。取得後タイトル行を除外する
listA = get_coldata('A')[1:]
listB = get_coldata('B')[1:]

listAを出力すると以下のようになります。

差分の取得

差分の取得は前回紹介したデータ型のSetを使用します。上記で取得したlistAとlistBをset型に変換して集合演算を行うことにより差分あるいは和集合を得ることができます。

データは以下の定義で取得することとします。
diffA: AにあってBにないもの、A-B
diffB: BにあってAにないもの、B-A
interAB: AとBの両方に存在する、A and B
unionAB: AとBの和集合、A or B

まずlistAとlistBをset型に変換してデータ内の重複を除去し、そのサイズを確かめます。
セットやリストのサイズは関数lenによって調べることができます。またprintは取得したデータを表示する関数です。

setA = set(listA)
setB = set(listB)

print(len(setA))
print(len(setB))

この結果により setA : 494件、setB: 965件を得ました。
では AとBの積集合(interAB)を求めて表示します。

interAB = list(setA & setB)
print(interAB)

この実行結果は以下の通りとなりました。25件が重複データとして取得されました。

その他のdiffA, diffB, unionAB の作成方法は以下の通りです。結果のリスト表示は割愛しますが是非実行して試してみてください。結果は diffA: 469件、diffB: 940件、unionAB: 1434件となります。

diffA = list(setA - setB)
diffB = list(setB - setA)
unionAB = list(setA | setB)

print(diffA)
print(diffB)
print(unionAB)

まとめ

今回は2列間の集合演算の方法について説明しました。ポイントはset型の使い方を知ることにあります。参考サイトへのリンクを掲載しますのでより詳しく知りたい方は参考にしてください。

Python, set型で集合演算(和集合、積集合や部分集合の判定など)https://note.nkmk.me/python-set/

set型以外のところでは関数を用いた点が難しかったかもしれません。関数については過去の記事やpythonの基本的な書籍やサイトを参照していただけたらと思います。

また今回紹介した方法以外にシート内のデータをリスト化する方法がありますが、python特有の書き方をするためわかりずらくなるので折をみて別途説明します。

次回はより実践的に使えるように、取得したデータをエクセルに書き出して保存する方法について説明します。