0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[NOTE] PythonでVLOOKUP的な機能を実現

0
Posted at

PythonでVlookup的な機能を実現して、二つの異なるデータベースでデータ2からデータ1の書式などをキープしたまま転記したい状況があるかと思います。
(※書式など転記しないのであれば、pandasのmergeで完結できるので、そういう方は別の記事を探してください)
本来、DB管理&DB同士が連携されていれば、こんなコードを書く必要もないのですが...システム改修に費用がかかる、各DBが管理者都合でEXCEL管理されている等々の理由でこういう状況に陥ってしまうときがあります。

import pandas as pd
from openpyxl import load_workbook
import shutil

### 複数列をまとめて転記する関数
def transfer_multiple_columns(
    path_base,
    path_ref,
    key_col_1,
    key_col_2,
    value_cols,
    sheet_base=None,
    sheet_ref=None,
    output_path=None,
    backup=True,
    key_as_str=True
):

    # 参照データ読み込み
    df2 = pd.read_excel(path_ref, sheet_name=sheet_ref)

    if key_as_str:
        df2[key_col_2] = df2[key_col_2].astype(str)

    # キー→複数列の辞書化
    mapping = df2.set_index(key_col_2)[value_cols].to_dict("index")

    # バックアップ
    if backup and output_path is None:
        shutil.copy(path_base, path_base.replace(".xlsx", "_backup.xlsx"))

    # 書き込むファイルの読み込み
    wb = load_workbook(path_base)
    ws = wb[sheet_base] if sheet_base else wb.active

    headers = [cell.value for cell in ws[1]]

    # 出力列の位置を確保(複数)
    output_col_index_map = {}
    for col in value_cols:
        if col not in headers:
            headers.append(col)
            ws.cell(row=1, column=len(headers), value=col)

        output_col_index_map[col] = headers.index(col) + 1

    # キー列
    if key_col_1 not in headers:
        raise ValueError(f"{key_col_1} が見つかりません")

    key_col_index = headers.index(key_col_1) + 1

    # 転記処理
    for row in range(2, ws.max_row + 1):
        key = ws.cell(row=row, column=key_col_index).value

        if key_as_str:
            key = str(key)

        row_data = mapping.get(key, {})

        for col in value_cols:
            value = row_data.get(col, None)
            ws.cell(row=row, column=output_col_index_map[col], value=value)

    # 保存
    save_path = output_path if output_path else path_base
    wb.save(save_path)

    print(f"完了: {save_path}")
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?