はじめに¶
セミナーの進め方¶
- ご質問に関して
- 講義中でも可能
- 質疑応答の時間にまとめて取り上げますので、一度チャット欄に投稿していただけると助かります
- 口頭で質問したい場合は、概要だけで構いません。質疑応答の時間にお答えします
- 講義後も可能
- 講義中でも可能
- 環境と資料に関して
環境は
Google Colab本セミナーでのコードは、
Google Colabで動作確認済み- 他の
Python実行環境でも利用可能ですが、環境ごとに仕様が異なるため、動作が変わることがある
- 他の
講義の方針に関して
厳密には正確でない部分がある場合もございますが、分かりやすさを重視
- 本セミナーでは初心者の方にも理解いただけるよう、例えを用いて解説
講義で扱った範囲内のトピック**に基づいて説明
- すべてのルールやパターンを網羅していない
講義資料
- コードのみ:セミナー中に送付
- 解説付きコード:本セミナー終了後に送付
トラブルシューティング
- 画面はCtrl キー+マウス ホイールで、拡大または縮小できます
※大きめに表示していますが、各自調整をお願いします。
ノートブックの読み込みエラーを防ぐため、無圧縮形式のzipファイルを使用しています。
※そのためファイルサイズが大きくなっていますが、ご了承ください。
目的¶
Pythonでデータ分析を行う上で、
NumPy、Pandas、Matplotlib は、いわばデータ分析の三種の神器です。
データ分析の三種の神器
┌────────┐ ┌────────┐ ┌────────┐
|🔢 NumPy | | 🐼 Pandas | |📊 Matplotlib |
└────────┘ └────────┘ └────────┘
その中で、Pandasを使用してデータ分析の基本を学ぶことを目的とします。
データの読み込みや加工、基本的な集計処理など、Pandasを活用したデータ操作のスキルを習得できる内容です。
講義はPythonの基礎を軽く押さえてから、データ分析の流れに沿って、Pandasを学びます。
以下のように改行して表示します:
申し訳ありません。では以下のように表示します:
環境とその準備¶
本講座では、Pythonの実行環境として Google Colab を使用します。
Google Colabはブラウザ上でPythonコードを実行できる無料のツールで、特別な環境設定が不要で簡単に始められます。
Google Colaboratoryとは?¶
Google Colaboratory(Colab)のノートブックを基盤にしています。
ノートブックとは、Word のように文章を書けて、Pythonのコードも実行できるものです。
つまり、マニュアル書のような役割も担えます。
- コードと説明を一体化できるため、手順や意図を明確に記録できる
- 別の人への引継ぎが可能になる
- 従来のエディタのコメントアウト機能の限界を打破する
など
Google Colab特有の機能は主に以下です。
- 主要ライブラリがインストール済み
- Geminiと連携済み
- 簡易的な自動コーディング機能を搭載
- Git Hubと連携可能
- クラッシュ時の自動復元
- ノートブックをワンクリックで共有可能
- 多発するバージョン不整合エラーが起きづらい(そのための仮想環境を作成せずに済む)
- 無料
など
Google Colab の準備方法¶
GoogleColab(https://colab.research.google.com/?hl=ja) にアクセスし、Googleアカウントでログインします。
-Googleアカウントがない方は、別途作成が必要です。
-Googleアカウント作成ページ(https://www.google.com/intl/ja/account/about/)
- [ファイル] メニューから [ドライブの新しいノートブック] をクリックします。
Googleドライブ(https://drive.google.com/drive/home)に自動的に[Colab Notebook]が作成され、そのノートブックがGoogleドライブに保存されます。
- 作成された
[Colab Notebook]に、講義資料として提供されたノートブックをアップロードします。
上記はパス指定せずに、実行できるフォルダになります。
別のフォルダにもアップロードできますが、 パス指定がややこしいので指定箇所にアップロードください。
Ptyhonとは何か¶
◎ 利用の増加
IOBE Index - TIOBE.「TIOBE Index」TIOBE、https://www.tiobe.com/tiobe-index/、アクセス日:2024年12月6日 より改変。
TIOBEインデックスの2024年11月のデータによると、Pythonは22.85%のレーティングを獲得し1位となっています。
(参考: TIOBE Index for November 2024)
前年同期比で8.69%増加しており、過去にも1位を獲得していることから、現在も利用がさらに拡大しています。
利用者が増えることで、多くのフォーラムやチュートリアルが充実し、学習や実務においての利便性が向上しています。
TIOBEインデックス=世界中の熟練エンジニアの数、コース、サードパーティベンダーの数に基づいてプログラミング言語の人気を測定する指標です。
└────────────────────────────────────────────────────────────┘
変数¶
変数とは、値を格納するための器です。
x = 10 # 数値型の変数
name ='Alice' # 文字列型の変数
📝 解説
本例は単純ですが、実際のプログラムではもっと複雑な値を扱うため、変数があると整理しやすくなります。
- 一度保存した値を何度も使え、同じ値を繰り返し書く手間が省ける
- 後で値を変えたくなったときも、一か所直すだけで済むので便利
など
age = 25 # int
price = 19.99 # float
is_student = True # bool
┌──────────────────────────────┐
🤖
Pythonは型を自動で判断する言語です。
数値を入れれば数値型、文字列を入れれば文字列型になります。
型を意識することで、バグが減り、より良いプログラムが書けます。
- なぜ型が大切?
- エラーを早く見つけられる(文字列+数値はできない)
- プログラムの品質
など
- ただし、以下の場合があるため注意
- 特定の機能は決まった型のみ使えないケースがある。例えば、
upper()は文字列だけ - ユーザーの意図とは異なる型を設定することがある
└──────────────────────────────┘
◎ データ構造
┌──────────────────────────┐
Pythonの標準装備
┌────────────────┐
リスト
リスト名 = [値1, 値2, 値3, ...]
└────────────────┘
┌────────────────┐
辞書
辞書名 = {キー1: 値1, キー2: 値2}
└┬┘
↓
ペア
└────────────────┘
┌────────────────┐
タプル
タプル名 = (値1, 値2, 値3, ...)
└────────────────┘
└──────────────────────────┘
┌──────────────────────────┐
外部ライブラリ (NumPy)
┌────────────────┐
NumPy配列
配列名 = np.array([値1, 値2, 値3])
└────────────────┘
└──────────────────────────┘
辞書(dict)型は複数の意味や関連情報を管理できる特徴があります。
一方、リスト、タプル、NumPy配列は主に1つの意味を扱う際に用います。
┌─────────┐
my_list ← 1つの意味を持つ情報を管理:リスト、タプル、NumPy配列
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
├─────────┤ リスト NumPy タプル
"Alice" (制限_少)←--------------------→(制限_多)
"Bob" ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
"Charlie"
└─────────┘
▲
│
│
▼
┌──────────┐
my_dict ←複数の意味を持つ情報を管理:辞書(dict)型
├──────────┤
"name": "Alice"
"age": 25
"job": "Engineer"
└──────────┘
my_list = ["Alice", "Bob", "Charlie"]
my_list
- リスト(
list)型- 最も基本的で柔軟な配列型
- 異なるデータ型の要素の格納が可
- 要素の追加、削除、変更が自由
[]での宣言
my_dict = {"name": "Alice", "age": 25, "job": "Engineer"}
my_dict
my_dict = {
"name": ["Alice", "Bob"],
"age": [25, 30],
"job": ["Engineer", "Doctor"]
}
my_dict
- 辞書(
dict)型:- キーと値のペアでのデータ管理
- キーでの要素アクセス
- {}での「キー:値」形式での宣言
my_tuple = ("Alice", "Bob", "Charlie")
my_tuple
- タプル(
tuple)型- リストに類似、要素変更不可
- 不変性が必要な場合に適性
()での宣言
import numpy as np
my_array = np.array(["Alice", "Bob", "Charlie"])
NumPy配列- 同一データ型のみの格納、要素数変更不可
NumPyライブラリでの使用
プログラムの処理の流れ¶
文部科学省. (2020). 高等学校情報科『情報Ⅰ』教員研修用教材(本編). 文部科学省. https://www.mext.go.jp/content/20200722-mxt_jogai02-100013300_005.pdf を参考に作成
1. 順次処理(命令を上から順番に実行)
┌──────┐
│ 処理1 │
└──┬───┘
│
│
▼
┌──────┐
│ 処理2 │
└──────┘
📌 上から順に処理が実行される
2. 分岐処理(条件分岐≒条件によって異なる処理を実行)
┌──────┐
│ 条件 │ ───┐
└──────┘ │
│ │
▼ ▼
┌──────┐ ┌──────┐
│ 処理1 │ │ 処理2 │
└──────┘ └──────┘
│ ⯇────┘
▼
[ 次の処理へ ]
📌 条件判定の結果に応じて 処理1 または 処理2 を実行
if x > 5:
print('xは5より大きい')
else:
print('xは5以下')
3. 反復処理(ループ≒条件を満たす間、同じ処理を繰り返す)
┌──────┐
│ ループ条件 │
└──┬───┘
│
▼
┌──────┐
│ ループ │
└──┬───┘
│
▼
┌──────┐
│ 処理 │
└──┬───┘
│└───────► (ループ継続)
│
▼
[ 終了 ]
📌 条件を満たす間は処理を繰り返し、満たさなくなったら終了
for i in [1, 2, 3, 4, 5]:
print(i)
📝 解説
リスト [1, 2, 3, 4, 5] の中の数字を順番に取り出して print(i) を実行する
for ~ in ...は、「ある期間の間、ずっと」という意味から派生していそうです。
富田一彦. (2011). The Word Book とみ単. 大和書房. を参考に作成。
for~in、:、 インデントのプログラム上の意味前置詞
for向かう
──が、到達ーーーしていない ⇒ その期間ずっと──▶ ーーーーー ●前置詞
in囲まれているイメージ ⇒ 範囲のある時間など
┌────┐ │ ● | └────┘:に関してfor文の宣言部分の終了を示す次の行から始まる繰り返し処理のブロックの開始を示す
前 後 ┌────┐ ┌────┐ │ A │ ≒ │ B │ └────┘ (同格) └────┘◎ コロンは前後のものを紐づける同格としての役割があり、「実行するのはこのブロックですよ」という意味を表現しています
インデントのプログラム上の意味
- 開始
- コロン(
:)で終わる行(例:if文、for文、関数定義など)の直後から始まる
- コロン(
- 範囲
- コロンの次の行から、同じインデントレベルが続く限りグループに属する
- 終了
- インデントが戻る(左に寄る)か、ファイルの終わりで終了する
for ループ: ← (コロン `:` でグループ開始) ┌──────────┐ │ 繰り返し処理 │ ← インデント開始:同じインデントレベルに統一 └──────────┘ ← インデント終了:処理の終了
- 開始
ライブラリの導入¶
データ分析には、Python標準ライブラリ以外に便利なツールが多数あります。
ライブラリは、PCに便利なソフトをインストールして使うようなものです。
自分ですべての処理を細かく書かなくても、あらかじめ用意された機能を使うことで、複雑な処理を簡単に実行できます。
┌────────┐ ┌──────────────┐
💻PC ◄─── 📖ライブラリ(≒(便利なソフト)
(Python環境) をインストール
└────────┘ └──────────────┘ ↖🤖
NumPyの使用準備¶
NumPyのインストール
NumPyを使用するには、まずPython環境にNumPyをインストールする必要があります。
インストールには、以下のように、どちらかのpip installを使用します。
ただし、Google Colabの環境下では、不要です。
#pip install numpy # コマンドラインやターミナルから実行する際に、推奨されている標準的なコマンドです
#!pip install numpy # Google Colabratory などのコードセルから実行する場合に、推奨されているコマンドです
Numpyのインポート
続いて、インストールしたライブラリをインポートにして、アクセスできるようにします。
import numpy as np
NumPyとは?NumPyは、Number(数や数学)とPythonを組み合わせた名前の通り、Pythonで数値データを効率よく扱うためのライブラリです。
Pandasの使用準備¶
Pandasのインストール
Pandasを使用するには、まずPython環境にPandasをインストールする必要があります。
インストールには、以下のように、どちらかのpip installを使用します。
ただし、Google Colabの環境下では、不要です。
#pip install pandas # コマンドラインやターミナルから実行する際に、推奨されている標準的なコマンドです
#!pip install pandas # Jupyter Notebook などのコードセルから実行する場合に、推奨されているコマンドです
Pandasのインポート
続いて、インストールしたライブラリをインポートにして、アクセスできるようにします。
import pandas as pd
PandasとはPandasの名前の由来はpan(el)-da(ta)-sという説があります。(もちろん、パネルデータ以外も扱えます)┌───────────────────┐
データ分析のためのPythonライブラリPandas←pan(el)-da(ta)-s└───────────────────┘
NumPyの配列とは異なり、Pandasのデータフレームを使うと、 データを表形式(テーブル形式)で管理できます。表形式(テーブル形式)とは、行と列からなるデータ構造であり、
Excelの表のようなイメージです。
┌─────────┐ ┌───────────┐
Excelの表 ≒Pandasのデータフレーム
└─────────┘ └───────────┘- 異なる型のデータ(数値や文字列など)を同じ表で扱える
→ 現実世界のデータ管理に近く、多様なデータを一つの表で整理できる - 各列に名前(ラベル)を付けられる
- 列や行ごとにデータを柔軟に操作できる
┌────────────────────────────────────┐
🤖↗Pandasの操作はExcelに近い体験を提供し、データ分析の初心者でも使いやすい- 異なる型のデータ(数値や文字列など)を同じ表で扱える
└────────────────────────────────────┘
Matplotlibの使用準備¶
Matplotlibのインストール
Matplotlibを使用するには、まずPython環境にMatplotlibをインストールする必要があります。
インストールには、以下のように、どちらかのpip installを使用します。
ただし、Google Colabの環境下では、不要です。
#pip install Matplotlib # コマンドラインやターミナルから実行する際に、推奨されている標準的なコマンドです
#!pip install Matplotlib # Jupyter ノートブック などのコードセルから実行する場合に、推奨されているコマンドです
Matplotlibのpyplotモジュールのインポート
続いて、インストールしたライブラリをインポートにして、アクセスできるようにします。
import matplotlib.pyplot as plt
Matplotlibとは?その名から連想される通り、
Matplotlibは、Pythonのデータ可視化ライブラリです。
データの読み込み¶
CSVやExcelファイルの読み込みPythonのライブラリを使うと、データファイルを簡単に読み込むことができます。
# CSVファイルを読み込んでデータフレームに変換
transactions = pd.read_csv('https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/transactions.csv')
transactions
pd(Pandas)ライブラリ
↑
pd.read_csv( 'https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/transactions.csv')
| └─> 読み込むファイルのURLを指定する
|
v
read_csv をデータフレームとして読み込む関数
→ 「CSVを読む(read)」 で、CSV形式のファイルを データフレームに変換する
Excelファイルの読み込み
# Excelファイルを読み込む
# transactions = pd.read_excel('https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/transactions.xlsx')
データの操作¶
行と列から成る表形式のデータフレームと呼びます。
データの確認¶
データの全体像や統計情報を確認します。
◎ head
オブジェクト.headにより、データの先頭行を表示し、
データの概要を把握します。
head()の名前の由来は「データの先頭 (head)」から来ています。
──────────────────────
head
▲
│
└──head = 先頭
──────────────────────
# 最初の5行を表示
transactions.head(10)
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
デフォルトは5行が表示されます。
行数を指定したい場合は、引数に数値を渡します。
例えば、df.head(1)とすると先頭1行が表示されます。
◎ info
オブジェクト.info()により、データの「情報」を簡潔にまとめます。
infoの名前の由来は「情報 (information)」から来ています。
──────────────────────
info
▲
│
└──info ≒ 情報
──────────────────────
# データの概要を確認
transactions.info()
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
<class 'pandas.core.frame.DataFrame'> ← データ型
RangeIndex: 100 entries, 0 to 99 ← 行数と行インデックスの範囲
Data columns (total 5 columns): ← 列数
──────────────────────────── 列のインデックス
| ──────────────────────── 各列の名称
| │ ─────────────────────── 各列の非欠損値の数
| │ │
| │ │ ───────── 各列のデータ型
| ↓ ↓ ↓
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 TransactionID 100 non-null int64
1 CustomerID 100 non-null int64
2 ProductID 100 non-null int64
3 Date 100 non-null object
4 Quantity 100 non-null int64
dtypes: int64(4), object(1) ← データ型の内訳
memory usage: 4.0+ KB ← メモリ使用量
| 項目 | 説明 |
|---|---|
<class 'pandas.core.frame.DataFrame'> |
← データ型 (DataFrame であることを示す) |
RangeIndex |
← 行数と行インデックス範囲 (例: 100行、インデックスは0~99) |
Data columns |
← 列数 (5列) |
# |
← 列のインデックス番号 |
Column |
← 列名 (例: TransactionID, CustomerIDなど) |
Non-Null Count |
← 各列の非欠損値の数 |
Dtype |
← 各列のデータ型 (例: int64, objectなど) |
dtypes |
← データ型の内訳 (例: int64型が4列、object型が1列) |
memory usage |
← メモリ使用量 (例: 4.0+ KB) |
None |
← メソッドの戻り値 (返り値がない) |
詳細は以下を参考にしてください。
「データの全貌を一目で把握!PandasのDataFrame.info()を使いこなそう | データ分析ドットコム」https://biz-data-analytics.com/python/11026/ (2025年1月17日)
⚠ データの型が違う場合のトラブルシューティング
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
上記の結果では、Date列がobject型(文字列型)として読み込まれています。
Date列を日付型にしないと、後々以下のような処理が面倒になる場合があります。
データのフィルタリング(特定の日付範囲のデータを抽出するなど)
日付の計算(例: 期間の差を計算する)
など
🛠️ 対処方法
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
read_csv()のparse_dates引数を使用して、Date列を日付型として読み込む必要があります。
parse_datesはその名前の通り、「日付を解析する(parse dates)」ためのものです。
──────────────────────
parse_dates
▲
│
└──「日付を解析する (parse_dates)」
──────────────────────
※読み込み後に、型変換する方法もあります。
🤖 ↘
┌──────────────────────────────┐
他の列の型も厳密に修正する必要があります。
TransactionID、CustomerID、ProductID がゼロ始まりの場合、
データの読み込み時に数値型で変換されるため、先頭の 0 が自動削除されます。
そのため、文字列型などに指定する必要があります。
└──────────────────────────────┘
◎ transactionsのDataFrameをメモリから削除
transactionsのDataFrameを日付型にして読み込むため、
一度、transactionsのDataFrameをメモリから削除します。
# transactionsのDataFrameをメモリから削除
del transactions
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
del: deleteの略で、指定した変数を削除します。
# 日付型を指定してデータを読み込む
transactions = pd.read_csv(
'https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/transactions.csv',
parse_dates=['Date']
)
Date列が日付型になっているかを確認します。
# データの型を確認
transactions.info()
info()でデータの概要を把握し、欠損値や列の型を確認・調整することが大切です。
◎ shape
オブジェクト.shapeにより、データの行数と列数を確認し、データのサイズを把握します。
shapeの名前の由来は「データの形状 (shape)」から来ています。
──────────────────────
shape
▲
│
└──shape ≒ 形状
──────────────────────
# データの形状を確認 (行数と列数)
transactions.shape
◎ describe
オブジェクト.describe()により、各列の基本統計量を確認し、現状を把握してビジネス課題の解決に活用。
describeの名前の由来は「記述 (describe)」から来ています。
──────────────────────
describe
▲
│
└──describe ≒ 記述
──────────────────────
# 各列の基本統計量を確認
transactions.describe()
列名
↓
TransactionID CustomerID ProductID Quantity
count → 100.000000 100.000000 100.000000 100.000000
mean → 1050.500000 28.730000 150.440000 4.730000
std → 29.011492 13.538464 29.165609 2.585332
min → 1001.000000 2.000000 101.000000 1.000000
25% → 1025.750000 20.750000 122.750000 3.000000
50% → 1050.500000 30.000000 154.500000 4.000000
75% → 1075.250000 39.250000 169.000000 7.000000
max → 1100.000000 50.000000 199.000000 9.000000
| 統計量 | 説明 |
|---|---|
| 'count' | 各列のデータポイント(レコード)の総数を示す |
| 'mean' | 各列の平均値を示す |
| 'std' | 各列の標準偏差を示し、データのばらつきを表す |
| 'min' | 各列の最小値を示す |
| '25%' | 各列の第1四分位点(全データを4等分した際の下位25%の境界)を示す |
| '50%' | 各列の中央値(データの中心値)を示す |
| '75%' | 各列の第3四分位点(全データを4等分した際の上位25%の境界)を示す |
| 'max' | 各列の最大値を示す |
🔒留意点 ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
非数値データが含まれる場合、デフォルトでは数値列のみが対象となりますが、include='all'を指定し、print(transactions.describe(include='all')) すべての列が出力されます。
オブジェクト.printにより、データ全体を表示します。
データを直感的に把握し、内容を確認する際に便利です。
printの名前の由来は表示する (print)から来ています。
──────────────────────
print
▲
│
└──print ≒ 表示
──────────────────────
◎ print
# データフレーム全体を表示する
print(transactions)
列名
↓
TransactionID CustomerID ProductID Quantity
0 1001 2 101 1
1 1002 4 150 3
2 1003 6 154 2
3 1004 8 199 5
4 1005 10 120 7
◎ 欠損値の確認
# 各列の欠損値の数を確認
transactions.isnull().sum()
📝 解説
Pandasオブジェクト.isnull().sum() で各列の欠損値の個数を確認できます。
───────────────────────────────
transactions.isnull().sum()
| └── .sum() : True=1のFalse=0の数を合計
↓.isnull() : 欠損値の有無の判定
├ 欠損値が存在する → True=1
└ 欠損値が存在しない → False=0
───────────────────────────────
❓ FAQ
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Q:
count() ではなく sum() を使用するのはなぜですか?
A:
transactions.isnull() は各セルが欠損値かどうかを True/False で示し、True は 1、False は 0 として扱われます。
そのため、sum() を使うと欠損値の数を正しく計算できます。
一方、count() は非欠損値の数を数えるため、欠損値の数を求めるのには適していません。
◎ 列を取り出すケース
📜 記法
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
〇 1列の場合
データフレーム['列名1'] と記述します
──────────────────────────────
データフレーム['列名']
└── '列名': 指定した列のデータを取り出す
──────────────────────────────
# 列を選択
transactions['Date']
📝 解説
データフレーム transactions の中から Date列を選択して出力します。
──────────────────────────────
transactions['Date']
└── Date: 指定した列のデータを取得
──────────────────────────────
〇 複数列を取り出すケース
📜 記法
⚠ 注意
- 1列を取り出すと 1次元データ(
Series型) - 複数列を取り出すと 2次元データ(
データフレーム型)
😔データ抽出時に1列は自動的に Series 型になるため、後の処理でエラーが発生することがあります。
# 複数の列を選択
transactions[['Date', 'CustomerID']]
📝 解説
データフレーム transactionsの中から Date列とCustomerID列を選択して出力します。
──────────────────────────────────
transactions[['Date', 'CustomerID']]
└── Date, CustomerID: 取得したいデータの列名をカンマで区切りで入力
──────────────────────────────────
◎ 行を取り出すケース
📜 記法
.ilocと.loc┌────────────────────────────┐
.iloc: データを取得するためのインデックス指定│
└────▶
iloc: integer location(整数の場所)↳ 行番号・列番号でアクセス
.loc: データを取得するためのインデックス指定│
└────▶
loc: location(場所)↳ ラベル(行・列の名前)でアクセス。インデックスはラベル扱いなので注意
└────────────────────────────┘
〇 1行選択
データフレーム.iloc[行番号] や データフレーム.loc[行名] で指定します。
───────────────────────────
データフレーム.iloc[行番号]
└─ 行番号: インデックス番号による指定行の取り出し
───────────────────────────
# 特定の行を選択
transactions.iloc[0] # 最初の行
📝 解説
データフレームのインデックス 0 の行(最初の行)を選択して出力します。
──────────────────────────────────
transactions.iloc[0]
└── インデックス 0 の行を取得
──────────────────────────────────
〇 複数行選択
データフレーム.iloc[開始:終了] での範囲指定します。
──────────────────────────────────────
データフレーム.iloc[開始:終了]
└─ 開始:終了: 範囲指定による複数行の取り出し(開始から終了-1の行)
──────────────────────────────────────
# 特定の行を選択
transactions.iloc[1:5]
📝 解説
データフレームのインデックス 1~4 の行(2行目から5行目)をスライスして出力します。
──────────────────────────────────
transactions.iloc[1:5]
└── インデックス 1~4 の行を取得
──────────────────────────────────
〇 条件を満たす行を取り出すケース
データフレーム[条件式] での条件指定し、行をと取り出します。
───────────────────────────
データフレーム[条件式] (例:データフレーム[データフレーム['Quantity'] > 4])
───────────────────────────
🔍 []をさらに詳しく
データフレーム[データフレーム['Quantity'] > 4] の外側 [] で「行の取り出し」、内側 [] で「列の指定」をしています。
データフレーム['Quantity']:Quantity列を指定データフレーム['Quantity'] > 4: この列に対して4より大きい値を持つ行を条件式として指定
────────────────────────────────
条件を満たす行の取り出し
↑
データフレーム[データフレーム['Quantity'] > 4]
└─ Quantity` 列 に対する条件設定
────────────────────────────────
# 条件を満たす行を抽出
filtered_data = transactions[transactions['Quantity'] > 4]
filtered_data
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
データフレーム transactions の中から Quantity 列の値が 4 より大きい行を抽出し、新しいデータフレーム filtered_data に格納して出力します。
transactions['Quantity'] > 4の部分でのQuantity列 に対する条件設定- その後、
transactions[...]での、条件を満たす行の取り出し
🔍 さらに詳しく言うと・・・
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
transactions['Quantity'] > 4がTrue/Falseを生成Trueの位置(行番号)を 記憶- 記憶した位置 の行を
transactionsから取り出す
└──────>実際は、True の位置の行を記憶して、取り出すという動作
データ加工¶
欠損値の処理¶
- 欠損値の除去
# 欠損値を含む行を削除
#transactions = transactions.dropna()
📝 解説
Pandasオブジェクト.dropna() で欠損値を含む行を削除できます。
───────────────────────────────
transactions = transactions.dropna()
└── .dropna() : 欠損値を含む行を削除するメソッド
│ │
│ └───▶ na:欠損値(Not Available)
│
└──────▶ drop:削除
───────────────────────────────
- 欠損値の補完
# 欠損値を特定の値で埋める
# transactions = transactions.fillna(0)
📝 解説
Pandasオブジェクト.fillna(値) で欠損値を、引数に指定した値で埋めることができます。
───────────────────────────────
transactions = transactions.fillna(0)
└── .fillna(値) : 欠損値を指定した値で埋めるメソッド
│ │
│ └───▶ na:欠損値(Not Available)
│
└──────▶ fill:埋める
───────────────────────────────
# データの読み込み
products = pd.read_csv('https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/master_products.csv')
customers = pd.read_csv('https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/master_customers.csv',parse_dates=['JoinDate'])
products.head()
customers.head()
customers.info()
別データから列の追加¶
transactions
# 売上額を計算して新しい列に追加
transactions['TotalAmount'] = transactions['Quantity'] * transactions['ProductID'].map(
products.set_index('ProductID')['Price']
)
transactions.head()
📝 解説
┌───>transactionsの購入数量
transactions['TotalAmount'] = transactions['Quantity'] * transactions['ProductID'].map(products.set_index('ProductID')['Price'])
│ ─
│ × 2つのデータのProductIDに対応する価格を取得
▼ │
新しい列TotalAmountが生成: │
新しい列名を指定して値を代入すると、 │
自動的にその列を作成する仕様 │
│
│
│
▼
📜 記法
`左データ['結合キー'].map(右データ.set_index('結合キー')['取得したい列'])`
結合キーをもとに 右データ から 取得したい列 の値を取得します。
ただし、取得した値を代入しない限り 左データ に列は追加されません。
set_index('結合キー')['取得したい列']は一般的なDataFrame操作の組み合わせです:
右テーブル.set_index('結合キー')はDataFrameオブジェクトを返す- その後、
['取得したい列']を使って特定の列を選択しているだけで、通常のdf[]の考え方と同じです
本例では、ProductID をもとに products から Price を取得し、transactions の Quantity と掛け算して TotalAmount を作成しています。
◎ マッピング操作の確認
以前出力した内容と照らし合わせることで、変換の正確性を確認します。
同じ個所、追加箇所がどうなっているかを確認します。
┌┈┈┈┈┈┈┈┈┐ 比較 ┌──────┐
before ◀──▶ after
データ データ
└┈┈┈┈┈┈┈┈┘ └──────┘
⚠️ 記録が必要
※新しく取得した列は、以下のコード実行後で違和感がないかで確認する
transactions.isnull().sum() # 欠損値の確認
通常、transactions.csv や master_products.csv に欠損値は存在しないはずです。
欠損値が発生した場合、以下の可能性を確認します。
transactions.csvまたはmaster_products.csvのデータ自体の問題- コードの指定ミスや参照カラムの誤り
transactions.head(10) # 最初の10行を表示
transactions.info() # データの概要を確認
transactions.shape # データの形状を確認(行数と列数)
transactions.describe() # 基本統計量を確認
😔 map() メソッドの確認方法はやや不便
ただし、このアプローチには不便な点があります。
本来、map() メソッドの利点は元のデータを保持したまま、新しい配列を作成することにあります。
そのため、次のような不便さが残ります。
- 元のデータと照らし合わせの不便さ
元のデータに対する確認メソッドの出力を保持しておく必要がある
計算に使用した列は、別途、
map()しないと追加されないため、計算の検算など
↓
この課題は、後述する
merge()メソッドを使用することで解決できます。merge()メソッド は元のデータを保持しながら、新しいデータを作成するためです。なお、
map()メソッドの利点はインデックスを生成しない点など多々あります。
別のデータを結合させ、新しいデータを作成¶
◎ transactionsをメモリから削除
mapを使って、transactionsを上書きしたため、一度、transactionsをメモリから削除します。
# transactionsをメモリから削除
del transactions
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
del: deleteの略で、指定した変数を削除します。
# 日付型を指定してデータを読み込む
transactions = pd.read_csv(
'https://www.salesanalytics.co.jp/wp-content/uploads/2025/01/transactions.csv',
parse_dates=['Date']
)
# transactionsとproductsのデータ結合
transactions_with_products = pd.merge(transactions, products, on='ProductID', how='left')
transactions_with_products.head()
📝 解説
┌──────────────────────────────────────────────────┐
transactionsとproductsをProductIDを基準に結合 (merge) し、
左側(left)のデータフレームのすべての行を保持 (how='left') します。
└──────────────────────────────────────────────────┘
💡コードと英語を結びつける記憶術
「どのように(how)」結合するかを決める際、
結合の接触対象の列を「on」で指定するイメージです。
┌─┐
│ │○ 前置詞の`on`は「接触」
└─┘
└──> 前置詞の「on」が「接触」を意味するように、2つのテーブル間の関連付けや条件に「基づく」結合を示します。
`how` ≒ 方法
──⯈ 「どのように」と訳され、何かを行う方法を示します。データ結合では、「どのように結合するか(方法)」を決めます。
◎ 結合操作の確認
以前出力した内容と照らし合わせることで、変換の正確性を確認します。
merge()メソッド は元のデータを保持しながら、新しいデータを作成します
そのため、mapメソッドより、照らし合わせが簡単です。
┌──────┐ 比較 ┌──────┐
before ◀──▶ after
データ データ
└──────┘ └──────┘
# 結合前後のデータの確認
print("=== 欠損値の比較 ===")
print("\n[結合前]")
print(transactions.isnull().sum())
print("\n[結合後]")
print(transactions_with_products.isnull().sum())
⌛ 補足
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
通常、transactions.csv や master_products.csv に欠損値は存在しないはずです。
欠損値が発生した場合、以下の可能性を確認します。
transactions.csvまたはmaster_products.csvのデータ自体の問題- コードの指定ミスや参照カラムの誤り
print("\n=== 最初の10行の比較 ===")
print("\n[結合前]")
print(transactions.head(10))
print("\n[結合後]")
print(transactions_with_products.head(10))
print("\n=== データの形状 (行数, 列数) の比較 ===")
print("\n[結合前]", transactions.shape)
print("\n[結合後]", transactions_with_products.shape)
print("\n=== 基本統計量の比較 ===")
print("\n[結合前]")
print(transactions.describe())
print("\n[結合後]")
print(transactions_with_products.describe())
❓ FAQ ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Q: データフレームの出力に \(バックスラッシュ)が付いているのですが、大丈夫ですか?
A: はい、問題ありません。
pandas のデータフレームで列が長すぎると折り返され、その目印として \ が挿入される。
Q: map()を使用した場合、一致しない ProductID があるとデータの一部は消えますか?
A: on=left のような動きです。データ自体は消えず、TotalAmount には NaN が入ります。
Q: map() の結合キーの型が一致しない場合、どうなりますか?
A: マッチングが正しく行われず、すべての値が NaN になります。事前に型を統一することが重要です。
Q: map() で計算に使用した列は、自動的にデータフレームに追加されますか?
A: いいえ、map() で取得した値は、指定した計算にのみ使われます。元のデータフレームには自動で追加されないため、計算結果の検算をする場合は、別途 map() で対応する列を追加する必要があります。
🔍ちょっと豆知識
────────────────────────────────────────────────────────────
map ≒ マッピング ──⯈ 既存データフレームに、別のデータから必要な値だけを引っ張ってくる操作
────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────
merge ≒ 結合 ──⯈ インデックス以外の列(キー)や複数の列(キー)を基準にしても結合でき、新しいデータフレームを作成
────────────────────────────────────────────────────────────
◎ CSVに保存
# 加工後のデータを保存
transactions_with_products.to_csv('transactions_with_products.csv', index=False)
📝 解説
┌──────────────────────────────────┐
transactions_with_productsデータフレーム を、行番号なしでtransactions_with_products.csv`に保存します
└──────────────────────────────────┘
transactions_with_productsデータフレーム
↖
transactions_with_products.to_csv('transactions_with_products.csv', index=False)
| └─>出力ファイル名を指定する └─>行番号を保存のオプション。False=保存しない
|
v
CSVに保存するメソッド
🔍ちょっと豆知識
`to` ≒ 「到達」
───→ ●
to は「到達」を意味し、データが 変換・出力 されることを示しています。
本例においては、
transactions_with_products.to_csv は データフレームを CSV に出力しています。
+-------------------------------------------+ to +--------+
transactions_with_products ─→ CSV
+-------------------------------------------+ +--------+
集計¶
単純集計¶
データ全体または特定のグループ全体に対して単一の集計操作を行う集計操作です。
単純集計(全体)
データ全体を対象した集計のことです。
# 合計、平均、中央値、ユニークな顧客数、トランザクション数の計算
total_sales = transactions['Quantity'].sum()
average_sales = transactions['Quantity'].mean()
median_sales = transactions['Quantity'].median()
unique_customers = transactions['CustomerID'].nunique()
total_transactions = transactions.shape[0]
print(total_sales, average_sales, median_sales, unique_customers, total_transactions)
📝 解説
┌──────────────────────────────────┐
transactionsのQuantity列を選択し、その列の値を合計します。
└──────────────────────────────────┘
transactions['Quantity'].sum()
| │
v └──────> SUM≒合計 ───┐
transactions の中から Quantity列を選択 |
v
┌┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┐
主なメソッド:
sum ≒ 合計
⯈ 指定された列の全行の値を加算して合計値を計算
mean ≒ 平均
⯈ 指定された列の値の合計を行数で割った平均値を計算
median ≒ 中央値
⯈ 指定された列の値を昇順に並べた際の中央に位置する値を計算
nunique ≒ ユニーク(重複がない)
⯈ 指定された列の中で重複を除いた値の個数を計算
shape ≒ サイズ
⯈ 行数と列数、shape[0]で行数を取得可能
など
└┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┘
単純集計(グループ別)
特定のグループの全体値を集計します。
グループ │ 値
─────┼────
項目1 │ XXX ─> グループごとの全体を示す
項目2 │ XXX
項目3 │ XXX
# グループ化して集計
sales_by_customerid = transactions.groupby('CustomerID')['Quantity'].sum()
sales_by_customerid
📝 解説
💡df['Quantity'].sumとは、操作上は同じイメージ
df['Quantity']に、groupbyメソッドを追加しているので、違うように見えるだけで、操作上は同じです。
◎ イメージ
- 通常選択 (
df['Quantity'].sum())
元のデータフレーム:
- グループ化後の列選択 (
df.groupby('Gender')['Quantity'].sum())
クロス集計¶
クロス集計の構成
2つの分類項目(
行と列)で区切られた表に、集計値を表示する分析手法です。クロス集計の構成は、
行、列、集計値の主に3つです。
主な3つの要素:
行:
- データを縦方向に分類する項目
- 例:性別(男性/女性)、年齢層など
列:
- データを横方向に分類する項目
- 例:商品カテゴリー、地域など
集計値: - 合計(売上金額など) - 平均(平均購入額など) - 件数(購入回数など) など
この3つの要素を組み合わせることで、データの関係性や傾向を分かりやすく把握することができます。
クロス集計
クロス集計は、データをカテゴリごとに分割して比較し、特定の関係性を明らかにする分析手法です。
商品のカテゴリごとに販売数量を集計したクロス集計表です。
主な目的は、商品カテゴリごとの販売行動を具体的に把握することです。
│
▼
┌┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┐
1点買い(数量が1)が多いカテゴリには個別割引を提供し、多点買い(数量が5以上)が多いカテゴリにはまとめ買い割引を適用するなど、購買パターンに応じたプロモーションを設計できます。
また、購買傾向を把握することで、在庫の調整や過不足の予防にもつながります。
└┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┘
◎ pivot_tableによるクロス集計
- 顧客ごとの平均購入数量をピボットテーブル形式で表示します。
- 分析目的: 顧客の購入パターンを視覚化し、購入習慣や重点的なマーケティング施策を特定するため。
# ピボットテーブル作成
pivot_example = transactions.pivot_table(values='Quantity', index='CustomerID', aggfunc='mean')
pivot_example.head()
📝 解説
(a)Excelピボットテーブル入門: 基本操作と構成要素の完全ガイド | データ分析ドットコム" .https://biz-data-analytics.com/excel/excel_pivottable/7881/, (2025/02/05)より改訂-
◎ crosstabによるクロス集計
### コード例:
# クロス集計表の作成
cross_tab_quantity = pd.crosstab(
index=transactions_with_products['Category'], columns=transactions_with_products['Quantity']
)
cross_tab_quantity
📝 解説
┌───────────────────────────────────────────────────────┐
transactions_with_productsのCategory列を行ラベル、Quantity列を列ラベルとするクロス集計表を作成し、各組み合わせの カウント(出現回数) を計算します。
└───────────────────────────────────────────────────────┘
┌───>Pandasのcrosstab関数:クロス集計表を作成
| └─ indexとcolumnsで指定された項目の組み合わせに基づいて集計
| └─ デフォルトの集計値は、行と列の値の組み合わせごとに 該当する組み合わせのカウント
|
pd.crosstab(index=transactions_with_products["Category"], columns=transactions_with_products["Quantity"])
└─>(1)Category列の値を基準にして行を構成する └─>(2)Quantity列の値を基準にして列を構成する
★ カテゴリごとの総売上
次に、map()の例と同様に、カテゴリ別の総売上を集計した例を示します。
カテゴリ別の総売上を集計する目的は、各カテゴリの売上規模を把握し、それに基づいて具体的なアクションを取るためです。
限られたリソースを効率的に配分します。
たとえば、
- 売上が高いカテゴリ(例: Clothing)には、広告投資の増加や品揃えの拡充などの施策を検討
- 売上が低いカテゴリ(例: Electronics)では、価格調整や新製品の導入を検討
| Category | Sales |
|---|---|
| Books | 21,369.16 |
| Clothing | 29,162.87 |
| Electronics | 13,201.19 |
| Home | 24,999.17 |
| Toys | 15,061.48 |
### コード例:
# 売上高を計算し、新しい列を追加
transactions_with_products['TotalAmount'] = (
transactions_with_products['Quantity'] * transactions_with_products['Price']
)
transactions_with_products
# カテゴリごとの売上高を求める
cross_tab_sales = transactions_with_products.pivot_table(
values='TotalAmount', index='Category', aggfunc='sum'
)
cross_tab_sales
📝 解説
┌──────────────────────────────────┐
transactions_with_productsを、TotalAmountの値をCategoryごとに合計(sum)します。
└──────────────────────────────────┘
pivot_table(values="TotalAmount", index="Category", aggfunc="sum")
└─>(1) └─>(2) └─>(3)
┌───────────┐
│ 'columns' │
───────┤───────────┤
'index'(2) │ (1)'value' │ ← (3)'aggfunc'で設定
───────└───────────┘
transactions_with_products
↖
transactions_with_products.pivot_table(values='TotalAmount',index='Category', aggfunc='sum')
| ↓ ↓ └─>集約関数(合計)
| 集計する値 行のグループ化の基準 |
| TotalAmount Category
| |
| |
| |
| v
| aggregation function(集約関数) で、集約方法を指定。 sum(合計)を設定
v
pivot_tableメソッド: 引数に指定した要件に従い、集計した新しい表を作成
データの可視化¶
データ可視化は、データの特性やパターンを視覚的に理解を補助します。
基本的なプロット¶
◎ 棒グラフ:カテゴリごとの総販売数量
# カテゴリごとの総販売数量を棒グラフで可視化
category_quantity = transactions_with_products.groupby('Category')['Quantity'].sum()
category_quantity
category_quantity.plot(kind='bar', color='skyblue')
# plt.title('Total Quantity Sold by Category')
# plt.xlabel('Category')
# plt.ylabel('Total Quantity')
# plt.xticks(rotation=45)
📝 解説
┌──────────────────────────────────┐
category_quantity を 棒グラフ (bar) として可視化、カラー (color='skyblue') を適用します。
└──────────────────────────────────┘
2行目コード=transactions_with_products.groupby('Category')['Quantity'].sum()
↓ ┌───>Pandasのplot メソッド: グラフとして可視化
category_quantity.plot(kind='bar', color='skyblue')
| └─> color='skyblue' グラフの色をスカイブルーに指定
↓
kind='bar' 棒グラフとして描画
┌──────────────────────────┐
- kind (≒ 種類) → グラフの種類を指定
- 'bar' (≒ 棒) → 棒グラフ
- 'line' (≒ 線) → 折れ線グラフ
- 'pie' (≒ 円) → 円グラフ など
補足
- kind を省略すると、'line' になる
└──────────────────────────┘
🔍ちょっと豆知識
◎ pandas の plot メソッド
pandas の plot メソッドは、matplotlib のラッパーとして機能します。
ラッパーとは「包む」という意味で、plot メソッドを通じて matplotlib の機能を簡単に呼び出せます。
しかも、matplotlib をインポートせずに使えます。ただし、インストールは必要です。
┌─────────┐ 呼び出し ┌┈┈┈┈┈┈┈┈┈┈┐
Pandasのplot ──► Matplotlib plot ──► グラフが描画される(表示)
ラッパー (実際の描画処理)
└─────────┘ └┈┈┈┈┈┈┈┈┈┈┘
★ plt.title
┌──────────────────────────────┐
タイトル (title) を追加し、グラフの内容を分かりやすくします。
└──────────────────────────────┘
Matplotlibライブラリ
↓ ┌───>title 関数: グラフにタイトルを追加
plt.title('Total Quantity Sold by Category')
└─> 設定するタイトルの文字列:設定したタイトルを入力する
★ xlabel、ylabel、xticks
✅グラフの軸ラベル (xlabel, ylabel) を設定し、 xticks を使って X 軸のラベルの回転角度を調整します。
┌──────────────────────────────────────────────┐
xlabel 関数: X 軸にラベルを設定
↓
plt.xlabel('Category')
└─> 'Category' X 軸に表示するラベル
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
ylabel 関数: Y 軸にラベルを設定
↓
plt.ylabel('Total Quantity')
└─> 'Total Quantity' Y 軸に表示するラベル
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
xticks 関数: X 軸の目盛りの回転角度を設定
↓
plt.xticks(rotation=45)
└─> rotation=45 X 軸のラベルを 45 度回転
┌─────────────────────────┐
xticks の引数
plt.xticks(rotation=...) を指定し、X 軸のラベルの見やすさを調整
rotation を省略すると、 0 度 (回転なし) になります。
- rotation (≒ 回転) → X 軸のラベルの向きを調整
- 0 (≒ そのまま) → ラベルを回転させずに表示
- 45 (≒ 45度回転) → ラベルを 右斜め 45 度 に回転
- 90 (≒ 縦向き) → ラベルを 垂直 (90 度回転) に配置 など
└──────────────────────────┘
└──────────────────────────────────────────────┘
# 日付ごとの累積売上を折れ線グラフで可視化
#transactions_with_products['Date'] = pd.to_datetime(transactions_with_products['Date'])
daily_sales = transactions_with_products.groupby('Date')['Price'].sum().cumsum()
daily_sales
FAQ
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Q: daily_sales の内容が Price と表示されますが、問題ありませんか?
A: 問題ないです。daily_sales は pandas.Series オブジェクトで、その名前が "Price" に設定されているためです。
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
transactions_with_products から 日別 (Date) の売上 (Price) を集計し、
その合計を 累積 (cumsum()) して 売上の推移 を計算します。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
transactions_with_products.groupby('Date')['Price'].sum().cumsum()
└─> .cumsum : 累積和を計算するメソッド
│
├──▶ cum: cumulative(累積の)
│ ↳ 先頭から順に値を足していく
│
└──▶ sum: sum(合計)
↳ 数値を合計する演算
│
↓
┌────────────────────────────────────────────────────────────┐
cumsum動作イメージ
─────────────────────────────────────────────────────────────
元のデータフレーム(一部):
+----------------+------------+------------+-------------+
| TransactionID | Date | Price | Category |
+----------------+------------+------------+-------------+
| 1001 | 2025-01-01 | 295.88 | Books |
| 1002 | 2025-01-02 | 1306.45 | Clothing |
| 1003 | 2025-01-03 | 432.50 | Home |
| 1004 | 2025-01-04 | 2444.96 | Electronics |
| 1005 | 2025-01-05 | 1135.28 | Electronics |
| ・・・ | ・・・ | ・・・ | ・・・ |
+----------------+------------+------------+-------------+
↓ .groupby('Date')['Price'].sum() を実行
日ごとの売上合計:
+------------+----------+
| Date | Price |
+------------+----------+
| 2025-01-01 | 295.88 |
| 2025-01-02 | 1306.45 |
| 2025-01-03 | 432.50 |
| 2025-01-04 | 2444.96 |
| 2025-01-05 | 1135.28 |
| ・・・ | ・・・ |
+------------+----------+
↓ .cumsum() を実行
累積売上の計算:
+------------+--------------+
| Date | Cumulative |
| | Sales |
+------------+--------------+
| 2025-01-01 | 295.88 |
| 2025-01-02 | 1602.33 |
| 2025-01-03 | 2034.83 |
| 2025-01-04 | 4479.79 |
| 2025-01-05 | 5615.07 |
| ・・・ | ・・・ |
+------------+--------------+
└───────────────────────────────────────────────────────────┘
# 例:日別の売上合計を累積する
元のデータフレーム:
+----------------+------------+------------+-------------+
| TransactionID | Date | Price | Category |
+----------------+------------+------------+-------------+
| 1001 | 2025-01-01 | 295.88 | Books |
| 1002 | 2025-01-02 | 1306.45 | Clothing |
| 1003 | 2025-01-03 | 432.50 | Home |
| 1004 | 2025-01-04 | 2444.96 | Electronics |
| 1005 | 2025-01-05 | 1135.28 | Electronics |
| ・・・ | ・・・ | ・・・ | ・・・ |
+----------------+------------+------------+-------------+
↓ `.groupby('Date')['Price'].sum()` を実行
日ごとの売上合計:
+------------+----------+
| Date | Price |
+------------+----------+
| 2025-01-01 | 295.88 |
| 2025-01-02 | 1306.45 |
| 2025-01-03 | 432.50 |
| 2025-01-04 | 2444.96 |
| 2025-01-05 | 1135.28 |
| ・・・ | ・・・ |
+------------+----------+
↓ `.cumsum()` を実行
累積売上の計算:
+------------+--------------+
| Date | Cumulative |
| | Sales |
+------------+--------------+
| 2025-01-01 | 295.88 |
| 2025-01-02 | 1602.33 |
| 2025-01-03 | 2034.83 |
| 2025-01-04 | 4479.79 |
| 2025-01-05 | 5615.07 |
+------------+--------------+
FAQ ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
Q: 時系列データで累積和を計算する前にソートは必要ですか?
A: 時系列データで累積和を計算する際は、まずsort_values()で日付順にソートしてからcumsum()を適用することをお勧めします。
groupby('Date')の時点で、Dateがインデックスになります。
# 日付でソートしてから計算
transactions_with_products.groupby('Date')['Price'].sum().sort_index(ascending=True).cumsum()
daily_sales.plot(kind='line', marker='o', color='green') #講義用にマーカーを設定
# makerなしのほうが見やすいため
daily_sales.plot(kind='line', color='green')
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
daily_salesを 折れ線グラフ (line) として可視化し、
データポイントにマーカー (marker='o') を追加し、線の色 (color='green') を指定します。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
daily_sales.plot(kind='line', marker='o', color='green')
│ │ └─> 線の色を緑に指定
│ │
│ └─> 各データポイントを円(●)で表示
│
↓
┌──────────────────────────────┐
折れ線グラフとして描画
──────────────────────────────
kind='line'により、折れ線グラフを描画- 引数を省略した場合は、'line'`(線) が適用
└──────────────────────────────┘
ヒストグラム¶
Pandasの場合¶
販売数量の分布をヒストグラムで可視化しました。
# 販売数量の分布をヒストグラムで可視化
transactions['Quantity'].plot(kind='hist', bins=10)
📝 解説
┌────────────────────────────────────────────────────────────┐
bins (≒ 箱) とは
┌────────────────────────────────────────────────────────────┐
bins はデータを区切る 箱(範囲) を意味し、
ヒストグラムで データの分布を可視化する際の区切り方 を決定します。
┌───────┐ ┌───────┐ ┌───────┐
│ │ │ │ │ │
│ bin=1 │ │ bin=2 │ │ bin=3 │ ・・・
│ │ │ │ │ │
└───────┘ └───────┘ └───────┘
データはbinsで指定した数の箱に分割されます。
多いと詳細が、少ないと全体像が見えやすくなります。
└────────────────────────────────────────────────────────────┘
🛤️ 学びの隣り道:seabornの場合¶
seabornでのヒストグラム作成します。
# 販売数量の分布をヒストグラムで可視化
import seaborn as sns
sns.histplot(transactions['Quantity'], bins=10,color='orange')
matplotlibでのヒストグラム作成
# matplolibでヒストグラム作成
plt.hist(transactions['Quantity'], bins=10)
plt.xlabel('Quantity')
plt.ylabel('Frequency')
plt.title('Distribution of Quantity')
plt.show()
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
transactionsの 'Quantity' 列を ヒストグラムhistplot として可視化しビン数 bins=10 を指定し、カラー color='orange' を適用します。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Pandasやmatplotlibには、ヒートマップを直接描画する専用関数は存在しません。
しかし、Seabornのsns.heatmap()関数を使用すれば、データの数値分布を視覚的に表現できます。
特に、クロス集計表が読みにくい場合に有効です。
× PandasのMatplotlibのラッパー には、ヒートマップを直接描画する専用関数は存在しない
──► 〇 Seaborn には sns.heatmap() というヒートマップを直接描画する専用関数が存在
cross_tab_quantity
### ヒートマップを使用したクロス集計の可視化:
import seaborn as sns
#import matplotlib.pyplot as plt
sns.heatmap(cross_tab_quantity, annot=True, fmt='d', cmap='Blues')
#plt.title('Category-wise Quantity Heatmap')
これらの手法を使用することで、データ間の関係を明確にし、効果的な分析を行うことができます。
📝 解説
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
cross_tab_quantityを ヒートマップ (heatmap) として可視化し、
セルに数値 (annot=True) を表示し、色 (cmap='Blues') を適用します。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
おわりに¶
学んだことの振り返り¶
- 🐍 なぜ、
Python?変数、データの型と構造、ライブラリなど - 📂
CSVやExcelのデータ読み込みなど - ✏️ データの確認、行列の参照など
- 🔧列の追加、結合など
- 📊単純集計とクロス集計ど
- 📈棒グラフ、ヒストグラム、ヒートマップなど
こられを通じて、Pythonのコードの構造と仕組みを学びました。
次のステップ¶
まず、本講義の復習です。今回学んだ内容を確実に自分のものにすることが大切です。
次は、本講義に立ち戻りながら、Excelで既に行ったデータ操作や視覚化をPythonで実現することに取り組みましょう。
ただし、Python プログラミングから学ぶのが、長期的には最も効果的です。
基礎があれば、次のステップに進む際もスムーズに成長できます。
+-----------+ ┌────» 📗Excel の操作を再現
| | │ ・📂データの読み込み
| |─┬ │ ・✏️データの操作
| 🐼Pandas | │ │ ・🔧データ加工
| | │ │ ・📊基本集計とクロス集計
+-----------+ │──▶ 📖本講義の復習 ・📈データの可視化
| | │ │
| 📖基礎 | │ │
| |─┴ │
| | └────» 🐍 Python プログラミングを学ぶ
+-----------+ ・🔢 データ型
・📦 変数
・🔀 条件分岐
・🔁 ループ
・🛠️ 関数
・📦 オブジェクト など