MENU

Pythonを用いたフォルダ選択とデータの読み込み

はじめに

このスクリプトは、フォルダ内の CSV および Excel ファイルを読み込み、データを pandas の DataFrame として取得するものです。

file_reader.py

ソースコード

import itertools
import tkinter as tk
from pathlib import Path
from tkinter import filedialog

import pandas as pd


def dir_selector():
    """フォルダ選択ダイアログを表示し、選択されたフォルダのパスを返す"""
    root = tk.Tk()
    root.withdraw()  # メインウィンドウを非表示
    folder_path = filedialog.askdirectory(
        title="インポートするフォルダを選択してください"
    )
    root.destroy()  # Tkinterウィンドウを破棄

    if folder_path:
        print(f"選択されたフォルダ: {folder_path}")
    else:
        print("フォルダ選択がキャンセルされました。")

    return folder_path


def read_csv(file_path):
    """CSVファイルをエンコーディングフォールバック付きで読み込む"""
    encodings = ["utf-8-sig", "cp932"]
    for encoding in encodings:
        try:
            return pd.read_csv(file_path, encoding=encoding)
        except UnicodeDecodeError:
            print(f"[CSVエンコーディングエラー] {file_path.name}: {encoding} で失敗")
        except Exception as e:
            print(f"[CSV読み込みエラー] {file_path.name}: {e}")
            return None
    print(f"[CSVエラー] {file_path.name}: 読み込み不可")
    return None


def read_excel(file_path):
    """Excelファイル(xlsx/xlsm)を読み込み、シートごとにDataFrameを返す"""
    try:
        with pd.ExcelFile(file_path, engine="openpyxl") as xls:
            return {
                f"{file_path.stem}_{sheet}": pd.read_excel(xls, sheet_name=sheet)
                for sheet in xls.sheet_names
            }
    except Exception as e:
        print(f"[Excelエラー] {file_path.name}: {e}")
        return {}


def read_files(dir_path):
    """指定フォルダ内のCSVおよびExcelファイルを読み込み、辞書形式でDataFrameを返す"""
    if not dir_path:
        print("[キャンセル] フォルダ選択がキャンセルされました。")
        return {}

    dir = Path(dir_path)
    if not dir.exists() or not dir.is_dir():
        print(f"[エラー] 指定されたフォルダが存在しません: {dir_path}")
        return {}

    data_frames = {}

    # CSVファイルの読み込み
    csv_files = list(dir.glob("*.csv"))
    if not csv_files:
        print("[情報] CSVファイルが見つかりませんでした。")

    for csv_file in csv_files:
        df = read_csv(csv_file)
        if df is not None:
            data_frames[csv_file.stem] = df
            print(f"[CSV読み込み] {csv_file.stem}: {df.shape[0]}行 × {df.shape[1]}列")

    # Excelファイルの読み込み(.xlsx / .xlsm)
    excel_files = list(itertools.chain(dir.glob("*.xlsx"), dir.glob("*.xlsm")))
    if not excel_files:
        print("[情報] Excelファイルが見つかりませんでした。")

    for excel_file in excel_files:
        excel_sheets = read_excel(excel_file)
        data_frames.update(excel_sheets)
        for name, df in excel_sheets.items():
            print(f"[Excel読み込み] {name}: {df.shape[0]}行 × {df.shape[1]}列")

    if not data_frames:
        print("\n[警告] 取得できるデータがありませんでした。")

    return data_frames

処理の概要

このスクリプトは以下の処理を行います。

  • フォルダ選択: dir_selector() でデータが格納されたフォルダを選択。
  • CSVファイルの読み込み: read_csv() でエンコーディングを考慮しながらデータを取得。
  • Excelファイルの読み込み: read_excel().xlsx.xlsm の各シートを DataFrame に変換。
  • ファイルリストを取得し、辞書形式でデータを格納

フォルダ選択

dir_selector() を使用して、データフォルダを選択します。

def dir_selector():
    root = tk.Tk()
    root.withdraw()
    folder_path = filedialog.askdirectory(title="インポートするフォルダを選択してください")
    root.destroy()

    if folder_path:
        print(f"選択されたフォルダ: {folder_path}")
    else:
        print("フォルダ選択がキャンセルされました。")
    
    return folder_path
  • filedialog.askdirectory() でフォルダ選択ダイアログを表示。
  • ユーザーがフォルダを選択すると、そのパスを取得。
  • root.withdraw() でメインウィンドウを非表示にし、root.destroy() で Tkinter のウィンドウを破棄。

CSVファイルの読み込み

read_csv() を使用して、複数のエンコーディングを試しながら CSV を読み込みます。

def read_csv(file_path):
    encodings = ["utf-8-sig", "cp932"]
    for encoding in encodings:
        try:
            return pd.read_csv(file_path, encoding=encoding)
        except UnicodeDecodeError:
            print(f"[CSVエンコーディングエラー] {file_path.name}: {encoding} で失敗")
        except Exception as e:
            print(f"[CSV読み込みエラー] {file_path.name}: {e}")
            return None
    print(f"[CSVエラー] {file_path.name}: 読み込み不可")
    return None
  • utf-8-sigcp932 の2種類のエンコーディングを試行。
  • 読み込みに失敗すると、エラーを表示し None を返す。

Excelファイルの読み込み

read_excel() を使用して、Excel ファイルを読み込み、シートごとに DataFrame を取得します。

def read_excel(file_path):
    try:
        with pd.ExcelFile(file_path, engine="openpyxl") as xls:
            return {
                f"{file_path.stem}_{sheet}": pd.read_excel(xls, sheet_name=sheet)
                for sheet in xls.sheet_names
            }
    except Exception as e:
        print(f"[Excelエラー] {file_path.name}: {e}")
        return {}
  • pd.ExcelFile() を使用し、openpyxl エンジンで Excel ファイルを開く。
  • 各シートを pd.read_excel() で DataFrame に変換。
  • シート名を {ファイル名}_{シート名} の形式で辞書のキーとして保存。

ファイルの一括読み込み

read_files() で、フォルダ内の CSV および Excel ファイルを一括で読み込みます。

def read_files(dir_path):
    if not dir_path:
        print("[キャンセル] フォルダ選択がキャンセルされました。")
        return {}
    
    dir = Path(dir_path)
    if not dir.exists() or not dir.is_dir():
        print(f"[エラー] 指定されたフォルダが存在しません: {dir_path}")
        return {}
    
    data_frames = {}
    
    # CSVファイルの読み込み
    for csv_file in dir.glob("*.csv"):
        df = read_csv(csv_file)
        if df is not None:
            data_frames[csv_file.stem] = df
            print(f"[CSV読み込み] {csv_file.stem}: {df.shape[0]}行 × {df.shape[1]}列")
    
    # Excelファイルの読み込み
    for excel_file in itertools.chain(dir.glob("*.xlsx"), dir.glob("*.xlsm")):
        excel_sheets = read_excel(excel_file)
        data_frames.update(excel_sheets)
        for name, df in excel_sheets.items():
            print(f"[Excel読み込み] {name}: {df.shape[0]}行 × {df.shape[1]}列")
    
    if not data_frames:
        print("\n[警告] 取得できるデータがありませんでした。")
    
    return data_frames
  • 指定フォルダ内の .csv.xlsx.xlsm ファイルを取得。
  • read_csv()read_excel() を使用してデータを読み込む。
  • 取得したデータを辞書に格納し、DataFrame として返す。

このスクリプトを活用することで、フォルダ内のデータを一括で読み込み、pandas の DataFrame として処理 できるようになります。

他モジュール

main.py

Pythonを用いたデータの読み込み・整形・統合・出力 

data_formatter.py

Pythonを用いたデータのフォーマット統一と統合処理

pivot_table_maker.py

Pythonを用いたピボットテーブルの作成

df_to_excel.py

Pythonを用いたDataFrame の Excel 出力と pickle 保存

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする