Python基礎

【保存版】pandas基礎:データフレームの作成・整形・結合・集計を“実務の型”で身につける

対象:未経験〜初学者/pandas 2.x・Python 3.10+ を想定
ゴール:読み込み→選択→整形→結合→集計→欠損→日時→ピボット→出力まで、実務でそのまま使える書き方を10ステップで習得

データ分析の9割は前処理と整形です。

ここが速くて正確だと、その後の可視化・モデル作成の質が一気に上がります。
本記事は未経験〜初学者が週10時間×2〜3週で、pandasの基礎(読み込み/選択/整形/結合/集計/欠損/日時/ピボット/出力)を実務でそのまま使える型で習得できるよう設計しました。
最後に、月末ミニプロジェクト(売上データの整形→可視化→示唆まとめ)まで作り切りましょう。

この記事で身につくこと

  • pandas 2.x の基本操作を実務の型で習得

  • loc/ilocgroupby/pivot使い分け基準

  • 欠損・重複・データ型の安全な扱い

  • メソッドチェーン & pipe による読みやすい整形フロー

  • Excel / CSV / Parquet への配布・保存テンプレ

まずは“つまずきポイント”を共有します

ここで迷いやすい分岐点を先に押さえましょう。判断軸を決めておくと、後工程の破綻が一気に減ります。

  • lociloc の違いが曖昧 → 意図せぬ抜き出しでバグる
  • groupbypivot_table の役割が混同 → 欲しい表が作れない
  • for で1行ずつ処理 → 遅い・壊れやすい
  • 欠損・重複・型の確認を後回し → 後工程で破綻

方針(現場メモ)

大手企業でのデータサイエンティスト歴10年、100件超の案件で最後に残ったのは 「再現可能で読みやすい整形コード」 でした。
ここでは
毎日使う最短手筋だけに絞ります。

前提とサンプルデータ

以降は import pandas as pd 前提で進めます。例では以下のCSVを使用します。

  • sales.csvdate, store, product, qty, price
  • stores.csvstore, area, open_date

ポイント

読み込みの時点で日付・カテゴリ型を決めると、以降の処理が安定します。

pandas“実務の型”10ステップ

1) 読み込み・基本確認(I/O)

何をしたい?

  • ファイルを読み込み、日付パース・型指定・欠損表現を最初に固定。
  • 先頭/末尾/情報/基本統計で中身を素早く把握
import pandas as pd

# CSV読み込み(日付パース/型指定/欠損値の文字列指定)

df = pd.read\_csv(
"sales.csv",
parse\_dates=\["date"],
dtype={"store": "category", "product": "category"},
na\_values=\["", "NA", "null"]
)

# 先頭/末尾/サマリ

print(df.head())
print(df.tail(3))
print(df.info())
print(df.describe(numeric\_only=True))

判断基準:I/Oの段階で日付とカテゴリ型を入れておくと、後工程が安定します。

2) 行・列の選択(loc/iloc/at/iat)

何をしたい?

  • 列選択条件抽出セル単位アクセスを安全に行う。
# 列選択
cols = ["date", "store", "qty", "price"]
df2 = df[cols]

# 行フィルタ(ブール)

mask = (df\["qty"] > 0) & (df\["price"] > 0)
df3 = df.loc\[mask]

# 位置ベース(iloc)、ラベルベース(loc)

row5 = df.iloc\[5]          # 5行目(0始まり)
subset = df.loc\[:, \["date", "store", "qty"]]

# 単一セルの高速アクセス

cell = df.at\[0, "qty"]

判断基準:
列名/行ラベルで取るloc位置で取るiloc
単一セルat/iat が高速

3) 列の生成・置換・削除(assign/rename/drop)

何をしたい?

  • メソッドチェーンで上から下へ“流れる”整形にする。
# 新列生成とメソッドチェーン
out = (
    df
    .assign(amount=lambda d: d["qty"] * d["price"],  # 売上金額
            ym=lambda d: d["date"].dt.to_period("M").astype(str))
    .rename(columns={"store": "store_id"})
)

# 列削除

out = out.drop(columns=\["product"])  # 不要なら落とす

判断基準assign→rename→drop の順で読みやすく再現可能に。

4) 欠損・重複の処理(isna/fillna/dropna/duplicated)

何をしたい?

  • 欠損の有無を把握し、目的に合う補完方法を選ぶ。重複はキーを決めて排除
# 欠損の確認
na_counts = df.isna().sum()

# 数値は中央値/平均、カテゴリは最頻値で補完の例

num\_cols = \["qty", "price"]
cat\_cols = \["store", "product"]

from statistics import median
fill\_values = {"qty": df\["qty"].median(), "price": df\["price"].median()}
df\["qty"] = df\["qty"].fillna(fill\_values\["qty"])
df\["price"] = df\["price"].fillna(fill\_values\["price"])

# 重複行の検出と削除(キーを指定)

dups = df.duplicated(subset=\["date", "store", "product"], keep="last")
df = df.loc\[\~dups].copy()

判断基準:補完の分析への影響(例:中央値→外れ値の影響を受けにくい)をコメントで残す。

5) 集計(groupby/agg/value_counts)

何をしたい?

  • 店舗×月の売上と数量を一発で集計し、ランキングも作る。
# 店舗×月の売上合計/数量合計
monthly = (
    out
    .groupby(["ym", "store_id"], as_index=False)
    .agg(sales=("amount", "sum"), qty=("qty", "sum"))
)

# 上位商品(単純集計)

rank = df\["product"].value\_counts().head(10).reset\_index(names=\["product", "count"])

判断基準as_index=Falseインデックス絡みの事故を避け、後工程を安定化。

6) ピボット(pivot_table)と整形(stack/unstack)

何をしたい?

  • レポート用にワイド表を作りつつ、必要に応じてロング⇄ワイドを往復。
# 月×店舗の売上ピボット(行:月、列:店舗)
pv = pd.pivot_table(
    data=monthly,
    index="ym", columns="store_id",
    values="sales", aggfunc="sum", fill_value=0
)

# ロング↔ワイド変換

long\_df = pv.reset\_index().melt(id\_vars="ym", var\_name="store\_id", value\_name="sales")

判断基準分析はロング、レポートはワイドが基本。melt/pivot でいつでも往復可能に。

7) 結合(merge)と参照データの付与

何をしたい?

  • マスタ(店舗情報など)を左結合で付与し、分析軸を増やす。
stores = pd.read_csv("stores.csv", parse_dates=["open_date"], dtype={"store": "category"})
# 左結合:売上に店舗属性を付与
joined = (
    df
    .merge(stores.rename(columns={"store": "store_id"}), on="store_id", how="left")
)

判断基準:結合前にキーの重複と型を必ず確認(value_counts, dtype)。

8) 日時・期間(dtアクセサ / resample / rolling)

何をしたい?

  • 週次集計や移動平均など時系列特有の処理を素直に書く。
# 週次の売上集計(リサンプリング)
weekly = (
    out
    .set_index("date")
    .resample("W-MON")
    .agg(sales=("amount", "sum"), qty=("qty", "sum"))
    .reset_index()
)

# 移動平均(直近4週)

weekly\["ma4"] = weekly\["sales"].rolling(window=4, min\_periods=1).mean()

判断基準:時系列はインデックスを日時にしてresample/rollingを使う。

9) 出力(CSV/Excel/Parquet)

何をしたい?

  • 配布再利用の両立。外部共有はExcel/CSV、内製の再計算はParquet。
# CSV(日本語環境のExcel向け:UTF-8 BOM)
monthly.to_csv("monthly_sales.csv", index=False, encoding="utf-8-sig")

# Excel(複数シート)

with pd.ExcelWriter("report.xlsx") as xw:
monthly.to\_excel(xw, sheet\_name="monthly", index=False)
rank.to\_excel(xw, sheet\_name="rank", index=False)

# Parquet(高速/省サイズ)

monthly.to\_parquet("monthly.parquet", index=False)

判断基準:反復利用前提ならParquet、配布はExcel/CSV

10) 高速化・可読性(vectorize/pipe/query)

何をしたい?

  • for 文を避けて**列演算(ベクトル化)**を使い、処理を小さな関数に分解。
# ベクトル化:行ループより列演算
out["unit_price"] = out["amount"] / out["qty"].where(out["qty"] != 0, other=pd.NA)

# pipeで処理を段階化

def add\_amount(d: pd.DataFrame) -> pd.DataFrame:
return d.assign(amount=d\["qty"] \* d\["price"])

def add\_ym(d: pd.DataFrame) -> pd.DataFrame:
return d.assign(ym=d\["date"].dt.to\_period("M").astype(str))

result = df.pipe(add\_amount).pipe(add\_ym)

# queryで可読性UP(※列名に空白/記号がない前提)

filtered = result.query("qty > 0 and price > 0 and store == 'A01'")

判断基準:行ループ禁止forで1行ずつ処理は極力しない)。pipe小さな関数に分ける。

最短で“業務で使える”到達にする学び方

  1. 本記事の10ステップをJupyterで順に実行し、都度ノートに判断基準を書き込む。
  2. sales.csvを自作(またはKaggleのサンプル)し、読み込み→整形→集計→出力関数化+pipeで再現。
  3. 仕上げにExcel出力Parquet保存まで実装して再現性を担保。

途中で詰まる人は、質問対応とレビューのあるスクールを併用すると挫折率が激減します。下のCTAから無料相談であなた専用の6ヶ月計画を作ってもらうのが近道です。

TechAcademy データサイエンスコース(受講料:174,600円~ ※更に割引あり)

TechAcademy 無料相談

株式会社キカガク AI人材長期育成コース(受講料:237,600円~)

キカガク 無料相談

ミニプロジェクト(提出推奨):店舗別×月別ダッシュボード素材を作る

  1. sales.csv を読み込み、amount=qty*priceym を作成。
  2. ym, storesales=sum(amount), qty=sum(qty) を集計。
  3. pivot_tableym×store のワイド表を作成し、report.xlsx に出力。
  4. 可視化(棒/折れ線)で上位店舗のトレンドを1枚に。
  5. 3行まとめで示唆を書いてREADMEに追記。

テンプレコード(そのまま実行→書き換え推奨)

import pandas as pd

def load\_sales(path: str) -> pd.DataFrame:
return pd.read\_csv(path, parse\_dates=\["date"], dtype={"store": "category", "product": "category"})

def make\_features(df: pd.DataFrame) -> pd.DataFrame:
return (
df.assign(amount=lambda d: d\["qty"] \* d\["price"],
ym=lambda d: d\["date"].dt.to\_period("M").astype(str))
)

def aggregate\_monthly(d: pd.DataFrame) -> pd.DataFrame:
return (
d.groupby(\["ym", "store"], as\_index=False)
.agg(sales=("amount", "sum"), qty=("qty", "sum"))
)

def pivot\_monthly(monthly: pd.DataFrame) -> pd.DataFrame:
return pd.pivot\_table(monthly, index="ym", columns="store", values="sales", aggfunc="sum", fill\_value=0)

if **name** == "**main**":
df = load\_sales("sales.csv")
monthly = aggregate\_monthly(make\_features(df))
pv = pivot\_monthly(monthly)
with pd.ExcelWriter("report.xlsx") as xw:
monthly.to\_excel(xw, sheet\_name="monthly", index=False)
pv.to\_excel(xw, sheet\_name="pivot")
print("Saved report.xlsx")

>>【保存版】可視化入門:Matplotlib/Plotlyの使い分けと“伝わるグラフ設計”10ステップ
>>【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得

付録A:よく使うレシピ集(コピペ可)

# 1) 条件で置換(マスク書き換え)
mask = (df["qty"] < 0)
df.loc[mask, "qty"] = 0

# 2) カテゴリ順序を固定

cat = pd.CategoricalDtype(\["S", "M", "L"], ordered=True)
df\["size"] = df\["size"].astype(cat)

# 3) 文字列→数値(通貨/カンマ除去)

df\["price"] = (df\["price"].astype(str)
.str.replace(",", "", regex=False)
.astype(float))

# 4) 正規表現で抽出

df\["sku"] = df\["text"].str.extract(r"SKU-(\d+)")

# 5) 異常値のWinsorize(上位1%を上限)

q99 = df\["amount"].quantile(0.99)
df\["amount\_clip"] = df\["amount"].clip(upper=q99)

# 6) 複数条件の一括集計

agg = df.groupby("store").agg(
sales=("amount", "sum"),
cnt=("amount", "size"),
avg=("amount", "mean")
).reset\_index()

付録B:メモリ・速度最適化の要点

  • 数値は最適な dtypeへ(int64→int32float64→float32 ※精度要件と相談)
  • 文字列キーは category 型へ(例:store/product
  • 必要な列だけ読み込み(usecols
  • 行ループ禁止。ベクトル演算/map/replace/where/clip を活用
  • 大規模は PolarsSQLite との併用も検討

FAQ:よくある質問

Q1. locilocの使い分けは?
A. ラベル指定loc位置指定iloc。単一セルはat/iatが高速。

Q2. groupbypivot_tableの違いは?
A. 集計の基本はgroupbyレポート向きのワイド表を作るならpivot_table。往復はmelt/pivot

Q3. Excel前提の現場だと?
A. ExcelWriter複数シート出力UTF-8 BOMで文字化け回避。テンプレ納品にすると時短。

Q4. 欠損はどう埋める?
A. 目的次第。中央値/最頻値/ゼロ埋め/「不明」カテゴリ化など、影響をコメントに残す。

Q5. これで機械学習に進める?
A. はい。pandasの整形→[内部リンク:scikit-learn基礎] に接続し、[内部リンク:モデル評価] へ。

この記事から次に読むべきもの(内部リンク)

スキルアップ
【実務で差がつく】pandas実践:欠損処理・結合・ウィンドウ関数・時系列・品質保証まで“読みやすく速い”型を習得

基礎文法の次は、実務で毎回出る処理を“型”として覚える段階です。 本記事は、pandas 2.x を前提に、欠損・外れ値・結合・ウィンドウ関数・時系列・カテゴリ処理・集計の自動化・大規模データの分割処 ...

可視化
【保存版】可視化入門:Matplotlib/Plotlyの使い分けと“伝わるグラフ設計”10ステップ

結論:可視化は「きれいに描く」ことではなく、意思決定を動かすための設計です。 本稿では、未経験〜初学者が 週10時間×1〜2週 で、Matplotlib/Plotlyを軸に “伝わるグラフ”の設計と実 ...

機械学習
【保存版】scikit-learn基礎:回帰・分類・前処理・パイプライン・交差検証を“実務の型”で習得

機械学習で迷子になる最大の理由は、前処理→学習→評価→改善の順番が曖昧なまま個々のアルゴリズムに飛びつくこと。 本記事は、未経験〜初学者が週10時間×2〜3週で到達できるscikit-learnの最短 ...

SQL
はじめてのSQL:SELECT/WHERE/GROUP BYを最短で理解【コピペOK】

データ分析・自動レポート・簡易アプリの土台はSQLです。Pythonだけで押し切るより、前処理の7割をDB側で完結させる方が速く・安定します。本記事は、未経験〜初 学者が週10時間×2〜3週で、SEL ...

SQLite
【保存版】SQLite×Pythonで作る“ローカルDWH”|ETL・集計・レポート自動化の最短手順

ローカルでゼロ構築、ファイル1つで完結、サーバ不要。 本記事はSQLite×Pythonで“毎日回る”ETL・集計・レポート自動化を最短で作るための完全ガイドです。データ設計→DB作成→ETL(取り込 ...

データレポート納品
【保存版】データレポート納品の型:要件定義→ETL→検証→可視化→Excel/PDF→引き継ぎまで、失注しないワークフロー完全版

“いい分析”より“伝わる納品”。副業や実務で評価されるのは、意思決定に効く1枚と再現できるパッケージを期限通り出せること。 本記事は、未経験〜初学者が 週10時間×2〜3週 で、要件定義 → データ受 ...

それでは、また次の記事でお会いしましょう。

最近のコメント

    • この記事を書いた人
    • 最新記事

    ふみと

    このブログでは、データサイエンティストとして市場価値を上げる方法を独自にまとめて発信しています。

    【プロフィール】
    ・大手企業データサイエンティスト/マーケティングサイエンティスト(10年、年収900万円台)/案件100件以上
    ・資格:JDLA E資格(日本ディープラーニング協会主催)/JDLA Community(CDLE会員)/Advanced Marketer/ビジネス統計スペシャリスト/統計検定2級/TOEIC 805
    ・スキル:Python/Tableau/SQL/機械学習/Deep Learning/RPA

    -Python基礎