📊 ステップ26: データの並び替えと集計
データを整理して、大切な情報を見つけよう!
ステップ25では、応用的なデータ抽出テクニックを学びました。今回は、データの並び替えと集計を学びます。データ分析では「売上が高い順に並べる」「各カテゴリの件数を数える」といった操作がとても重要です。
📖 このステップで学ぶこと
・sort_values()でデータを並び替える
・value_counts()で値の出現回数を集計する
・unique()で重複を除いた値を取得する
・nunique()でユニークな値の個数を数える
・実践例:ランキング作成
学習時間の目安: 2.5〜3時間
🎯 1. データの並び替えとは?
データ分析では、データを並び替えて見やすくすることがとても大切です。並び替えることで、データの傾向やパターンが見えやすくなります。
💡 並び替えが必要な場面
・売上が高い順に商品を並べて、人気商品を見つける
・点数が高い順に生徒を並べて、成績ランキングを作る
・日付順にデータを並べて、時系列の変化を確認する
・名前のあいうえお順に並べて、検索しやすくする
🔰 並び替えの2つの方向
並び替えには2つの方向があります。
📌 昇順と降順
| 用語 | 意味 | 例 |
| 昇順(しょうじゅん) | 小さい → 大きい | 1, 2, 3, 4, 5 / あ, い, う, え, お |
| 降順(こうじゅん) | 大きい → 小さい | 5, 4, 3, 2, 1 / お, え, う, い, あ |
↕️ 2. sort_values()で並び替え
sort_values()は、DataFrameを指定した列の値で並び替えるメソッドです。「values(値)をsort(並び替え)する」という名前の通り、データを整理するのに使います。
🔰 基本的な並び替え(昇順)
📝 sort_values()の書き方
df.sort_values(‘列名’) → 昇順(小さい→大きい)で並び替え
df.sort_values(‘列名’, ascending=False) → 降順(大きい→小さい)で並び替え
・デフォルトは昇順(ascending=True)です
・元のDataFrameは変更されず、新しいDataFrameが返されます
コード:昇順で並び替え
# Pandasをインポート
import pandas as pd
# 成績データを作成
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'数学': [85, 92, 78, 95, 88],
'英語': [90, 88, 85, 92, 79],
'国語': [78, 95, 88, 85, 92]
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print()
# 数学の点数で並び替え(昇順 = 小さい順)
sorted_df = df.sort_values('数学')
print("数学の点数で並び替え(昇順):")
print(sorted_df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 名前 数学 英語 国語 0 太郎 85 90 78 1 花子 92 88 95 2 次郎 78 85 88 3 美咲 95 92 85 4 健太 88 79 92 数学の点数で並び替え(昇順): 名前 数学 英語 国語 2 次郎 78 85 88 0 太郎 85 90 78 4 健太 88 79 92 1 花子 92 88 95 3 美咲 95 92 85
💡 コードの解説
df.sort_values(‘数学’)
・「数学」列の値を基準に並び替えます
・デフォルトは昇順(小さい→大きい)
・78 → 85 → 88 → 92 → 95 の順になりました
左端のインデックス番号に注目
・元のインデックス(0, 1, 2, 3, 4)がそのまま付いてきます
・2, 0, 4, 1, 3 の順番になっています
・これは元の行がどこにあったかを示しています
📝 降順(大きい順)に並び替え
ランキングを作る時など、「大きい順」に並べたい場合はascending=Falseを指定します。
コード:降順で並び替え
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'数学': [85, 92, 78, 95, 88]
}
df = pd.DataFrame(data)
# 数学の点数で並び替え(降順 = 大きい順)
sorted_df = df.sort_values('数学', ascending=False)
print("数学の点数で並び替え(降順):")
print(sorted_df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
数学の点数で並び替え(降順): 名前 数学 3 美咲 95 1 花子 92 4 健太 88 0 太郎 85 2 次郎 78
💡 ascending(アセンディング)の意味
ascendingは「上昇する」という意味の英語です。
ascending=True(デフォルト)
・値が「上昇」していく = 昇順(小さい→大きい)
ascending=False
・値が「上昇」しない = 降順(大きい→小さい)
📘 複数の列で並び替え
複数の列を基準に並び替えることもできます。「まず数学で並べて、同点の場合は英語で並べる」といった指定が可能です。
📝 複数列で並び替えの書き方
df.sort_values([‘列1’, ‘列2’])
・列1で並び替え、同じ値の場合は列2で並び替え
df.sort_values([‘列1’, ‘列2’], ascending=[True, False])
・列1は昇順、列2は降順で並び替え
コード:複数列で並び替え
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'学年': [2, 1, 2, 3, 1],
'点数': [85, 92, 88, 95, 89]
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print()
# 学年(昇順)、同じ学年なら点数(降順)で並び替え
sorted_df = df.sort_values(['学年', '点数'], ascending=[True, False])
print("学年(昇順)→ 点数(降順):")
print(sorted_df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ: 名前 学年 点数 0 太郎 2 85 1 花子 1 92 2 次郎 2 88 3 美咲 3 95 4 健太 1 89 学年(昇順)→ 点数(降順): 名前 学年 点数 1 花子 1 92 4 健太 1 89 2 次郎 2 88 0 太郎 2 85 3 美咲 3 95
💡 コードの解説
ascending=[True, False]
・最初の列(学年)は昇順(True): 1年 → 2年 → 3年
・2番目の列(点数)は降順(False): 高い点数から
結果を見ると:
・1年生が最初(花子92点、健太89点)
・同じ1年生の中では、点数が高い順
・次に2年生(次郎88点、太郎85点)
・最後に3年生(美咲95点)
🔄 インデックスをリセットする
並び替え後、インデックス番号がバラバラになります。0から振り直したい場合はreset_index()を使います。
コード:インデックスをリセット
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'数学': [85, 92, 78, 95, 88]
}
df = pd.DataFrame(data)
# 並び替え後、インデックスを0から振り直す
sorted_df = df.sort_values('数学', ascending=False)
sorted_df = sorted_df.reset_index(drop=True)
print("インデックスをリセット:")
print(sorted_df)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
インデックスをリセット: 名前 数学 0 美咲 95 1 花子 92 2 健太 88 3 太郎 85 4 次郎 78
💡 reset_index(drop=True)の意味
reset_index():インデックスを0から振り直す
drop=True:古いインデックスを捨てる
drop=False(デフォルト):古いインデックスを列として残す
通常はdrop=Trueを指定して、古いインデックスを削除します。
📈 3. value_counts()で集計
value_counts()は、各値が何回出現するかを数えます。例えば「りんごが4個、バナナが3個」のように集計できます。
🔰 値の出現回数を数える
📝 value_counts()の書き方
Series.value_counts() → 各値の出現回数を集計
df[‘列名’].value_counts() → 特定の列で集計
・結果は自動的に多い順に並びます
・結果はSeriesで返されます
コード:値の出現回数を集計
import pandas as pd
# 販売データを作成
sales_data = {
'商品': ['りんご', 'バナナ', 'りんご', 'みかん', 'バナナ',
'りんご', 'ぶどう', 'バナナ', 'りんご', 'みかん'],
'個数': [3, 5, 2, 4, 3, 1, 6, 2, 4, 3],
'地域': ['東京', '大阪', '東京', '名古屋', '大阪',
'東京', '名古屋', '東京', '大阪', '名古屋']
}
df = pd.DataFrame(sales_data)
print("元のデータ:")
print(df)
print()
# 商品ごとの販売回数を集計
print("商品ごとの販売回数:")
print(df['商品'].value_counts())
print()
# 地域ごとの販売回数を集計
print("地域ごとの販売回数:")
print(df['地域'].value_counts())
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ:
商品 個数 地域
0 りんご 3 東京
1 バナナ 5 大阪
2 りんご 2 東京
3 みかん 4 名古屋
4 バナナ 3 大阪
5 りんご 1 東京
6 ぶどう 6 名古屋
7 バナナ 2 東京
8 りんご 4 大阪
9 みかん 3 名古屋
商品ごとの販売回数:
商品
りんご 4
バナナ 3
みかん 2
ぶどう 1
Name: count, dtype: int64
地域ごとの販売回数:
地域
東京 4
大阪 3
名古屋 3
Name: count, dtype: int64
💡 コードの解説
df[‘商品’].value_counts()
・「商品」列の各値が何回出現するかを集計
・りんごは4回、バナナは3回、みかんは2回、ぶどうは1回
・自動的に多い順に並びます
これを見ると「りんごが一番売れている」ことがわかります!
📝 割合(パーセント)で表示
normalize=Trueを指定すると、件数ではなく割合で表示できます。
コード:割合で表示
import pandas as pd
sales_data = {
'商品': ['りんご', 'バナナ', 'りんご', 'みかん', 'バナナ',
'りんご', 'ぶどう', 'バナナ', 'りんご', 'みかん']
}
df = pd.DataFrame(sales_data)
# 割合を計算(normalize=True)
print("商品の割合:")
percentages = df['商品'].value_counts(normalize=True)
print(percentages)
print()
# パーセントで表示(×100)
print("パーセント表示:")
print(percentages * 100)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
商品の割合: 商品 りんご 0.4 バナナ 0.3 みかん 0.2 ぶどう 0.1 Name: proportion, dtype: float64 パーセント表示: 商品 りんご 40.0 バナナ 30.0 みかん 20.0 ぶどう 10.0 Name: proportion, dtype: float64
💡 normalize=Trueの使い道
割合がわかると、データの構成比が理解しやすくなります。
例:「りんごは全体の40%を占めている」
・件数だけだと「4個」
・割合だと「40%」(全体の4割)
レポートや分析では、割合の方がわかりやすい場面も多いです。
🔍 4. unique()で重複削除
unique()は、重複を除いた値を返します。「どんな種類のデータがあるか」を確認する時に使います。
🔰 ユニークな値を取得
📝 unique()とnunique()の書き方
df[‘列名’].unique() → 重複を除いた値の配列を返す
df[‘列名’].nunique() → ユニークな値の個数を返す
・unique()は値のリスト、nunique()は個数を返します
コード:ユニークな値を取得
import pandas as pd
sales_data = {
'商品': ['りんご', 'バナナ', 'りんご', 'みかん', 'バナナ',
'りんご', 'ぶどう', 'バナナ', 'りんご', 'みかん'],
'地域': ['東京', '大阪', '東京', '名古屋', '大阪',
'東京', '名古屋', '東京', '大阪', '名古屋']
}
df = pd.DataFrame(sales_data)
# 商品の種類を確認
print("商品の種類:")
unique_products = df['商品'].unique()
print(unique_products)
print(f"→ 全部で{len(unique_products)}種類")
print()
# nunique()で直接個数を取得
print("ユニーク数を直接取得:")
n_products = df['商品'].nunique()
n_regions = df['地域'].nunique()
print(f"商品の種類: {n_products}種類")
print(f"地域の数: {n_regions}地域")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
商品の種類: ['りんご' 'バナナ' 'みかん' 'ぶどう'] → 全部で4種類 ユニーク数を直接取得: 商品の種類: 4種類 地域の数: 3地域
📌 unique()とvalue_counts()の違い
| メソッド | 返すもの | 使用例 |
| unique() | ユニークな値のリスト | [‘りんご’, ‘バナナ’, ‘みかん’, ‘ぶどう’] |
| value_counts() | 各値の出現回数 | りんご: 4, バナナ: 3, みかん: 2, ぶどう: 1 |
| nunique() | ユニークな値の個数 | 4(種類数だけ) |
🏆 5. 実践例:ランキング作成
ここまで学んだ並び替えを使って、実際にランキングを作成してみましょう。
📊 売上ランキングの作成
コード:売上ランキング作成
import pandas as pd
# 月別の商品売上データ
monthly_sales = {
'商品名': ['ノートPC', 'タブレット', 'スマートフォン', 'イヤホン',
'キーボード', 'マウス', 'モニター', 'Webカメラ'],
'売上金額': [5800000, 3200000, 8500000, 1200000,
450000, 380000, 2100000, 680000]
}
df = pd.DataFrame(monthly_sales)
print("元のデータ:")
print(df)
print()
# ステップ1: 売上順に並び替え(大きい順)
df_sorted = df.sort_values('売上金額', ascending=False)
# ステップ2: インデックスをリセット
df_sorted = df_sorted.reset_index(drop=True)
# ステップ3: 順位を追加
df_sorted['順位'] = range(1, len(df_sorted) + 1)
# ステップ4: 列の順番を変更(順位を最初に)
df_sorted = df_sorted[['順位', '商品名', '売上金額']]
print("売上ランキング TOP 8:")
print(df_sorted)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
元のデータ:
商品名 売上金額
0 ノートPC 5800000
1 タブレット 3200000
2 スマートフォン 8500000
3 イヤホン 1200000
4 キーボード 450000
5 マウス 380000
6 モニター 2100000
7 Webカメラ 680000
売上ランキング TOP 8:
順位 商品名 売上金額
0 1 スマートフォン 8500000
1 2 ノートPC 5800000
2 3 タブレット 3200000
3 4 モニター 2100000
4 5 イヤホン 1200000
5 6 Webカメラ 680000
6 7 キーボード 450000
7 8 マウス 380000
💡 ランキング作成の手順
ステップ1:売上金額で降順に並び替え
ステップ2:インデックスを0から振り直す
ステップ3:順位列を追加(1, 2, 3, …)
ステップ4:列の順番を整理
range(1, len(df_sorted) + 1)
・1から始まる連番を生成
・len(df_sorted)はデータの行数
・range(1, 9)で[1, 2, 3, 4, 5, 6, 7, 8]が生成されます
📊 TOP Nの抽出
コード:TOP 3を抽出
import pandas as pd
# 売上データ
sales_data = {
'商品': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
'売上': [450, 890, 230, 670, 920, 340, 780, 560, 410, 850]
}
df = pd.DataFrame(sales_data)
# 売上TOP 5を取得
print("売上TOP 5:")
top5 = df.sort_values('売上', ascending=False).head(5)
print(top5)
print()
# 売上BOTTOM 3を取得(ワーストランキング)
print("売上BOTTOM 3:")
bottom3 = df.sort_values('売上', ascending=True).head(3)
print(bottom3)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
売上TOP 5: 商品 売上 4 E 920 1 B 890 9 J 850 6 G 780 3 D 670 売上BOTTOM 3: 商品 売上 2 C 230 5 F 340 8 I 410
💡 head()との組み合わせ
sort_values().head(N)
・並び替えた後、上位N件だけを取得
・TOP 5なら.head(5)
ワーストランキング
・昇順(ascending=True)で並び替えてhead()
・一番小さい値から順に取得できます
📝 練習問題
ここまで学んだことを、実際に手を動かして確認しましょう。
問題1:基本的な並び替え(初級)
📋 問題
以下のデータを「価格」の高い順に並び替えてください。
・商品: [‘ペン’, ‘ノート’, ‘消しゴム’, ‘定規’, ‘ホッチキス’]
・価格: [120, 200, 80, 150, 350]
解答例を見る
コード
import pandas as pd
data = {
'商品': ['ペン', 'ノート', '消しゴム', '定規', 'ホッチキス'],
'価格': [120, 200, 80, 150, 350]
}
df = pd.DataFrame(data)
# 価格の高い順に並び替え
sorted_df = df.sort_values('価格', ascending=False)
print(sorted_df)
実行結果
商品 価格 4 ホッチキス 350 1 ノート 200 3 定規 150 0 ペン 120 2 消しゴム 80
問題2:value_counts()の基本(初級)
📋 問題
以下の果物のリストで、各果物が何個ずつあるか集計してください。
fruits = [‘りんご’, ‘バナナ’, ‘りんご’, ‘みかん’, ‘バナナ’, ‘りんご’, ‘みかん’, ‘りんご’, ‘バナナ’, ‘りんご’]
解答例を見る
コード
import pandas as pd
fruits = ['りんご', 'バナナ', 'りんご', 'みかん', 'バナナ',
'りんご', 'みかん', 'りんご', 'バナナ', 'りんご']
fruits_series = pd.Series(fruits)
# 各果物の個数を集計
counts = fruits_series.value_counts()
print(counts)
print(f"\n最も多いのは{counts.index[0]}で{counts.iloc[0]}個です")
実行結果
りんご 5 バナナ 3 みかん 2 Name: count, dtype: int64 最も多いのはりんごで5個です
問題3:複数列での並び替え(中級)
📋 問題
以下の学生データを「学年」の昇順、同じ学年の場合は「点数」の降順で並び替えてください。
・名前: [‘太郎’, ‘花子’, ‘次郎’, ‘美咲’, ‘健太’]
・学年: [2, 1, 2, 3, 1]
・点数: [85, 92, 88, 95, 89]
解答例を見る
コード
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'学年': [2, 1, 2, 3, 1],
'点数': [85, 92, 88, 95, 89]
}
df = pd.DataFrame(data)
# 学年(昇順)、点数(降順)で並び替え
sorted_df = df.sort_values(['学年', '点数'], ascending=[True, False])
print(sorted_df)
実行結果
名前 学年 点数 1 花子 1 92 4 健太 1 89 2 次郎 2 88 0 太郎 2 85 3 美咲 3 95
問題4:売上TOP 3を表示(中級)
📋 問題
以下の商品データから、売上金額のTOP 3を表示し、順位を付けてください。
・商品名: [‘商品A’, ‘商品B’, ‘商品C’, ‘商品D’, ‘商品E’, ‘商品F’, ‘商品G’, ‘商品H’]
・売上金額: [1200000, 850000, 2300000, 950000, 1800000, 670000, 1500000, 1100000]
解答例を見る
コード
import pandas as pd
data = {
'商品名': ['商品A', '商品B', '商品C', '商品D', '商品E',
'商品F', '商品G', '商品H'],
'売上金額': [1200000, 850000, 2300000, 950000,
1800000, 670000, 1500000, 1100000]
}
df = pd.DataFrame(data)
# 売上金額順に並び替えてTOP3を抽出
top3 = df.sort_values('売上金額', ascending=False).head(3)
top3 = top3.reset_index(drop=True)
# 順位を追加
top3['順位'] = range(1, 4)
# 列の順番を変更
top3 = top3[['順位', '商品名', '売上金額']]
print("売上TOP 3:")
print(top3)
実行結果
売上TOP 3: 順位 商品名 売上金額 0 1 商品C 2300000 1 2 商品E 1800000 2 3 商品G 1500000
問題5:カテゴリ別集計(上級)
📋 問題
以下のデータについて、地域ごとの販売回数を集計し、割合(パーセント)も表示してください。
・地域: [‘東京’, ‘大阪’, ‘東京’, ‘名古屋’, ‘大阪’, ‘東京’, ‘福岡’, ‘大阪’, ‘東京’, ‘名古屋’]
解答例を見る
コード
import pandas as pd
data = {
'地域': ['東京', '大阪', '東京', '名古屋', '大阪',
'東京', '福岡', '大阪', '東京', '名古屋']
}
df = pd.DataFrame(data)
# 地域ごとの販売回数
print("地域ごとの販売回数:")
counts = df['地域'].value_counts()
print(counts)
print()
# 割合(パーセント)
print("地域ごとの割合(%):")
percentages = df['地域'].value_counts(normalize=True) * 100
print(percentages)
print()
# ユニークな地域数
print(f"地域の種類: {df['地域'].nunique()}地域")
実行結果
地域ごとの販売回数: 地域 東京 4 大阪 3 名古屋 2 福岡 1 Name: count, dtype: int64 地域ごとの割合(%): 地域 東京 40.0 大阪 30.0 名古屋 20.0 福岡 10.0 Name: proportion, dtype: float64 地域の種類: 4地域
問題6:総合演習(上級)
📋 問題
以下のアンケートデータから、評価を数値化(excellent=4, good=3, fair=2, poor=1)して、平均評価が高い順に並べてください。
・名前: [‘Aさん’, ‘Bさん’, ‘Cさん’, ‘Dさん’, ‘Eさん’]
・評価: [‘excellent’, ‘good’, ‘fair’, ‘excellent’, ‘good’]
解答例を見る
コード
import pandas as pd
data = {
'名前': ['Aさん', 'Bさん', 'Cさん', 'Dさん', 'Eさん'],
'評価': ['excellent', 'good', 'fair', 'excellent', 'good']
}
df = pd.DataFrame(data)
print("元のデータ:")
print(df)
print()
# 評価を数値化
rating_map = {
'excellent': 4,
'good': 3,
'fair': 2,
'poor': 1
}
df['評価数値'] = df['評価'].map(rating_map)
print("数値化したデータ:")
print(df)
print()
# 評価が高い順に並び替え
sorted_df = df.sort_values('評価数値', ascending=False)
print("評価が高い順:")
print(sorted_df)
print()
# 評価の集計
print("評価の集計:")
print(df['評価'].value_counts())
実行結果
元のデータ:
名前 評価
0 Aさん excellent
1 Bさん good
2 Cさん fair
3 Dさん excellent
4 Eさん good
数値化したデータ:
名前 評価 評価数値
0 Aさん excellent 4
1 Bさん good 3
2 Cさん fair 2
3 Dさん excellent 4
4 Eさん good 3
評価が高い順:
名前 評価 評価数値
0 Aさん excellent 4
3 Dさん excellent 4
1 Bさん good 3
4 Eさん good 3
2 Cさん fair 2
評価の集計:
評価
excellent 2
good 2
fair 1
Name: count, dtype: int64
🎯 このステップのまとめ
✅ 学んだこと
✓ sort_values()でデータを並び替えられる
✓ ascending=Falseで降順(大きい→小さい)に並び替え
✓ value_counts()で各値の出現回数を集計できる
✓ normalize=Trueで割合を計算できる
✓ unique()で重複を除いた値を取得できる
✓ nunique()でユニークな値の個数を数えられる
✓ 複数の列で並び替えができる
✓ ランキング作成などの実践的な処理ができる
💡 次のステップに進む前に確認
以下のことができるようになったか確認しましょう:
□ sort_values()で並び替えができますか?
□ value_counts()で集計できますか?
□ unique()とvalue_counts()の違いがわかりますか?
□ 複数列での並び替えができますか?
□ TOP Nの抽出ができますか?
これらができたら、次のステップに進みましょう!
❓ よくある質問
Q1: sort_values()は元のDataFrameを変更しますか?
A: いいえ、元のDataFrameは変更されません。並び替えた結果は新しいDataFrameとして返されます。元のDataFrameを変更したい場合は、df.sort_values('列名', inplace=True)を使います。
Q2: value_counts()とgroupby()の違いは?
A: value_counts()は単純に各値の出現回数を数えます。groupby()はグループごとに様々な集計(合計、平均など)ができます。value_counts()は集計の特殊な形と考えるとわかりやすいです。
Q3: 並び替え後、インデックスが飛び飛びになるのはなぜ?
A: 並び替えても、元の行のインデックス番号がそのまま付いてくるからです。インデックスを0から振り直したい場合は、reset_index(drop=True)を使いましょう。
Q4: 欠損値(NaN)がある場合、並び替えはどうなりますか?
A: デフォルトでは、NaNは最後に配置されます。これはna_position='last'が初期設定だからです。最初に配置したい場合はna_position='first'を指定します。
Q5: 文字列の列でも並び替えできますか?
A: はい、できます。文字列はアルファベット順(日本語はUnicodeの順序)で並び替えられます。「あいうえお順」に近い順番になりますが、完全な50音順ではない場合があります。
学習メモ
Pythonデータ分析入門 - Step 26