最近、AIが進展し現場での活用推進が始まっている。
製造現場では、毎日大量の製造データができる。現場が自主的に分析できたら強みになる。
AIに指示したら使えるプログラムを作ってくれるという。

しかし、無料AIには、現場の機密データを提供するなと。
有償AIならば、機密保持ができるが、無料AIならば全世界にデータを公開するのと同義だ。

そこで、使える手法としては、列名を抽象的なものとして、AIにプログラム作成を依頼したら、機密は漏れない
データそのものは提供しないから。
例えば、AIへの依頼内容を下記にする。

製造日、品種、製造数、不良1,不良2、不良3・・・、などと記述し、それを集計し不良率を計算し、不良率高い順に並べるプログラムを作って。
データ例は、サンプルデータを作るプログラムを作れとAIに依頼すればよい。即座に作ってくれる。

このように依頼して、実際のデータの列名を上記に変更すれば、使えるプログラムを手に入れることができる。動作結果も確認できる。

使う場合は、ユーザーは、見出し行の列名を入れ替えるだけでよい。

また、Polarsには、膨大なCSVの列の中で、特定の列だけを選択して読み込む機能もある。

読み込むときの便利機能
1.指定項目読み込み定義を指定(文字、数字、論理値など)
  3桁ごとのコンマの除去方法あり
2.項目名を、項目名変換辞書で一括変更
3.膨大な項目の場合、指定項目のみ読み込む

事例紹介

 エクセルデータを分析するプログラムをAI(Copilot)に作ってと依頼したら、とんでもなく長いコードを提示してきたという。
 システム担当は、支援を拒否した。メンテナンス不能だから現場の責任で利用してほしいと。
 コードをみたら、VBで作っていた。膨大な行数だった。やることは単純なはずなのに、エクセルのファイルでVBで作ったためだ。
 特定のエクセルだけに通用する膨大なVBのプログラムの解読やメンテナンスは、専門家でも不可能だ。

目的を聞いたら、製造日報のエクセル元資料、ロットごとに、製造数・不良原因別不良数 のデータの集計と不良率高いものを調べたいと。

これに対して、AIのGeminiにPolarsを使ったプログラムを書いてと依頼した結果を下記紹介する。
データは、製造日、品名、製造数、不良1~不良5 という形式のCSVとした。
できたプログラムでは、不良項目数の制限はない。「不良+数」の項目を全て取り込んでくれる。

Geminiが提示したプログラムは、無修正で動作し、瞬時にファイルを読み込み、計算し、画面に表示した。
また、結果は、必要に応じてファイルに書き出すことも可能だ。
なによりも、短く、説明付きなので、読んで意味が解読できる

元データを読み込み、各行の不良の数全部集計し、縦方向で品名毎に製造数と不良数の総計計算し、それで総計表を作り、不良率高い順に並べる。

そして、このプログラムならば、システム部門はメンテナンスや、アドバイスにも応じてくれるだろうし、AIに改善や異なる内容への対応も依頼しやすく、できたものの理解もしやすいだろう。

重要: Polarsは、文字コードは UTF-8だけエクセルの標準がShift-JISなので、データCSV作成時にUTF-8へコード変換。
 エクセル > ファイル > 名前を付けて保存 > ファイルの種類 > CSV UTF-8 (コンマ区切り) (*.csv) を選択

結果は、これ。品名はテストデータで自動作成したもの。
実際のデータを入れたら、品名は製造品名になります。

コードです。そのまま、貼り付けると動作します。
Polars 不良集計し・不良率・不良高い順表示プログラム

 

import datetime
import polars as pl
# ==========================================
# STEP  Polarsによるデータ集計・分析
# ==========================================
def analyze_production_data(filename="production_data.csv"):    #関数宣言
    # 1. CSVデータの読み込み
    df = pl.read_csv(filename)
    
    # 2. 各行の不良数合計(不良1〜5)を計算し、新しい列「総不良数」を追加
    # pl.sum_horizontal を使うことで、行方向の計算を高速に行えます
    df_with_total_defects = df.with_columns(
        pl.sum_horizontal(pl.col(r"^不良\d+$")).alias("総不良数")  
           #各行で「不良+数」の列全て合計し「総不良数」列を作れ
    )
    
    # 3. 品名ごとにグループ化して、製造数と総不良数を合計
    summary_df = df_with_total_defects.group_by("品名").agg(
        pl.col("製造数").sum().alias("総製造数"),
        pl.col("総不良数").sum().alias("総不良数")
    )
    
    # 4. 不良率の計算とソート
    # 不良率 = 総不良数 / 総製造数
    result_df = summary_df.with_columns(
        (pl.col("総不良数") / pl.col("総製造数")).alias("不良率")
    ).sort("不良率", descending=True) # descending=True で高い順(降順)
    
    # 5. 結果の表示(不良率はパーセント表記で見やすくするためにフォーマットを適用することも可能ですが、ここでは生値)
    print("--- 不良率が高い順の集計結果 ---")
    print(result_df)
    
    # 必要に応じてCSVやExcelに書き出し可能
    # result_df.write_csv("summary_result.csv")
 
if __name__ == "__main__":           #関数実行するぞ
    # 事前に pip install polars が必要です
    analyze_production_data()

 

なお、サンプルプログラム(元データ)を作ってと依頼したら作ってくれたのが下記のPolars プログラム
これを使って、上記のデータ分析プログラムを検証できた。
品名5種類、不良1~不良5、生産数と不良数それぞれ埋めてテストデータ作れ。

import datetime
import random
import polars as pl
# ==========================================
# STEP  サンプルCSVデータの生成
# ==========================================
def create_sample_csv(filename="production_data.csv"):        #関数宣言
    products = ["製品A", "製品B", "製品C", "製品D", "製品E"]
    start_date = datetime.date(2026, 7, 1)
    
    # CSVのヘッダー
    headers = ["製造年月日", "品名", "製造数", "不良1", "不良2", "不良3", "不良4", "不良5"]
    
    data_rows = []
    
    # 5品種 × 10日間 = 50行のデータを生成
    for day in range(10):
        current_date = start_date + datetime.timedelta(days=day)
        for prod in products:
            # 製造数は10から100のランダム
            make_count = random.randint(10, 100)
            
            # 不良数は製造数を超えないように、かつ現実的な範囲(各0〜3個程度)でランダム生成
            defect1 = random.randint(0, min(3, make_count // 5))
            defect2 = random.randint(0, min(3, make_count // 5))
            defect3 = random.randint(0, min(3, make_count // 5))
            defect4 = random.randint(0, min(3, make_count // 5))
            defect5 = random.randint(0, min(3, make_count // 5))
            
            row = [
                current_date.strftime("%Y-%m-%d"),
                prod,
                make_count,
                defect1,
                defect2,
                defect3,
                defect4,
                defect5
            ]
            data_rows.append(row)
            
    # ファイル書き込み
    with open(filename, "w", encoding="utf-8") as f:
        f.write(",".join(headers) + "\n")
        for row in data_rows:
            f.write(",".join(map(str, row)) + "\n")
            
    print(f"サンプルデータを作成しました: {filename}\n")
if __name__ == "__main__":                 #関数実行するぞ
    # 事前に pip install polars が必要です
    create_sample_csv()

特定の列を指定して読み込みたい場合

PolarsにはCSVの特定の列だけを指定して効率的に読み込む機能がしっかりと用意されています。
主に以下の2つのアプローチがあり、用途(すぐにデータをメモリに載せるか、巨大なデータで処理を最適化するか)によって使い分けが可能です。

1. pl.read_csv() の columns 引数を使う方法(即時読み込み)

ファイルサイズがそれほど大きくなく、通常のデータフレーム(DataFrame)として即座にメモリに読み込みたい場合は、pl.read_csv() の columns 引数を使用します。

コード例

Python

import polars as pl
# 列名(文字列)で指定する場合
df = pl.read_csv("data.csv", columns=["ユーザーID", "売上金額"])
 
# 列のインデックス(0始まりの数値)で指定する場合
df = pl.read_csv("data.csv", columns=[0, 3])
 
💡 ポイント: Pandasの usecols 引数にあたるものが、Polarsでは columns になります。

 

2. pl.scan_csv() + .select() を使う方法(遅延評価・推奨)

データサイズが非常に大きい(数GB以上など)場合は、こちらの方法が圧倒的におすすめです。

pl.scan_csv() は、実行した時点ではデータをメモリに読み込まず、どのような処理を行うかという「計画(プラン)」だけを作成します(遅延評価 / Lazy API)。
その後に .select() で必要な列を指定し、最後に .collect() を呼び出すことで、Polarsの最適化エンジンが「指定された列だけをファイルからスキャンして読み込む」処理を自動的に実行してくれます。

コード例

Python

import polars as pl
# 読み込みの計画を作成し、必要な列だけを選択
df = (
    pl.scan_csv("large_data.csv")
    .select(["ユーザーID", "売上金額"])
    .collect()
)

💡 ポイント: 引数に余計なオプションを詰め込まなくても、メソッドチェーンで直感的に書くだけで内部的に最速の読み込みを行ってくれる