カラムAとカラムBに含まれる文字数を比較する python スクリプトを作成してみた

カラムAとカラムBに含まれる文字数を比較する python スクリプトを作成してみた

Clock Icon2024.09.04

こんにちは!よしななです。

今回は、カラムAとカラムBをに含まれる文字数を比較する python スクリプトを作成し実行したので、備忘録としてブログに残します。

目次

  • 実現したいこと
  • 対象環境
  • 事前準備
    • フォルダ構成
    • 仮想環境の立ち上げ
    • ライブラリのインストール
  • 実行したスクリプト
  • スクリプトの説明
    • 関数:longest_match_length について
    • 関数:process_csv について
  • 実行結果
  • まとめ

実現したいこと

カラムAとカラムBにそれぞれ含まれる文字列を比較し、一致する文字列をカウントし返す処理をしたい。

〇例1:
文字列A:綺麗な沖縄の海~フェリーに乗って夏の旅~
文字列B:綺麗な沖縄の空

→"綺麗な沖縄の"までが一致するため、6を返す処理

〇例2:
文字列A:吾輩は猫である
文字列B:青空文庫

→一致する文字列はないため、0を返す処理

〇スクリプトの流れ

  • 文字列A、文字列Bが入った.csvを読み込み
  • 文字列A、文字列Bを比較し一致する文字列をカウントする
  • 結果を.csvに出力する

という流れでスクリプトを作成してみます。

対象環境

本記事で実行した対象環境は以下となります。

  • OS
    • windows11
  • エディタ
    • VSCode

事前準備

フォルダ構成

本記事でのフォルダ構成は以下となります。
polars_testフォルダを作成し、.py を以下の通り配置します。

2024-09-02_15h19_50

仮想環境の立ち上げ

.py を配置したら、仮想環境(.venv)を立ち上げます。
https://dev.classmethod.jp/articles/venv-jupyternotebook/#toc-2 を参照し、.venv 環境を作成します。
次に.venv/Script/activateを PowerShell で実行し、.venv 環境を起動します。

.venv/Scripts/activate

ライブラリのインストール

venv 環境を起動したら、polars のインストールを行います。
venv 環境が起動している状態で、pip install polarsを実行します。
venv 環境内にpolarsライブラリがインストールされました。

pip polars install

スクリプトを作成

事前準備が完了したら、polars_test.pyスクリプトを作成します。
作成したスクリプトは以下となります。

import polars as pl
from difflib import SequenceMatcher

def longest_match_length(a: str, b: str) -> int:
    return SequenceMatcher(None, a, b).find_longest_match(0, len(a), 0, len(b)).size

def process_csv(input_path: str, output_path: str) -> None:
    try:
        # CSVファイルの読み込み
        df = pl.read_csv(input_path, infer_schema_length=0)

        # カラム間の比較を行い、新しいカラムに一致する最長の文字列の長さを格納
        df = df.with_columns(
            pl.struct(pl.col('stringa'), pl.col('stringb'))
            .map_elements(lambda x: longest_match_length(str(x['stringa']), str(x['stringb'])))
            .alias('Matching_Length')
        )

        # 結果を新しいCSVファイルに保存
        df.write_csv(output_path)
        print(f"処理が完了しました。結果は {output_path} に保存されました。")

    except Exception as e:
        print(f"エラーが発生しました: {e}")

if __name__ == "__main__":
    INPUT_PATH = '文字列を比較したい .csv が格納されたパス名'
    OUTPUT_PATH = '出力結果先'
    process_csv(INPUT_PATH, OUTPUT_PATH)

スクリプトの説明

関数:longest_match_length について

こちらの関数は、2つの文字列abを入力として受け取り、SequenceMatcherクラスを使用して、abの文字列を比較しています。
find_longest_matchメソッドを使用して、文字列ab内で文字が一致する部分を見つけた後、見つかった最長一致部分の長さを返す関数となります。

関数:process_csv について

CSV 読み込み

polars のread_csvを使用し、csv の中身をデータフレームとして読み込みします。

https://docs.pola.rs/api/python/stable/reference/api/polars.read_csv.html

カラム間の比較とカラムの追加

ここでは作成した関数:longest_match_lengthを使用し、カラム間の比較を行い、新しいカラムに一致する最長の文字列の長さを追加する処理を行っています。

  1. DataFrame のstringastringbカラムを選択します。
  1. 各行のstringastringbの値をlongest_match_length関数に渡して処理します。
  1. 処理結果を新しいカラムMatching_Lengthとして追加します。

csv書き出し

polars のwrite_csvを使用し、データフレームを csv に書き出します。

https://docs.pola.rs/api/python/stable/reference/api/polars.DataFrame.write_csv.html

実行結果

実行前

実行前のファイルは以下の通りです。

2024-09-04_15h13_54

実行後

スクリプトの実行後、以下の通り .csv ファイルが出力され、文字列を比較した数が返っていることを確認しました。

2024-09-04_15h16_30

以上で、「カラムAとカラムBに含まれる文字数を比較する python スクリプトを作成してみた」は以上となります。

まとめ

map_elementsについて、今回は2行のみのため処理速度について遅さは感じなかったのですが、csv の行数が多いと処理速度が遅くなったり…といったことがあるそうです。
次回以降の記事で、データ量が増えた場合の書き方についても調べたいなと思いました。
ここまで読んでいただき、ありがとうございました!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.