この記事でわかること

  • 店舗のようなグループごとに、上位の行を取り出す方法(sort_valuesとgroupbyのhead)
  • 並べ替えを忘れると、上位ではない行が出る理由
  • 境目に同じ売上が並んだときと、店舗が空欄の行の扱い
  • 取り出した表を、行の番号を付けずに保存する方法

店舗ごとに売上の上位3件を報告したいとき、Excelで店舗ごとにフィルターをかけ、並べ替えては上から3行ずつ写していませんか。この記事では、全部の店舗の上位の行を、pandasで一度に取り出すやり方をまとめます。

説明の元にしたのは、pandas 3.1.0の公式の資料(groupbyのheadとnlargest、sort_values、groupby)で、2026年10月31日に原文を確かめました。売上の表は、手順を見せるために作った架空のコーヒー豆の売上です。

先に結論: 店舗の中で売上の大きい順に並べてから、店舗ごとに先頭の行を取る

sort_valuesで店舗の中を売上の大きい順にし、groupbyのheadで店舗ごとに先頭の3行を取ります。 headは並べ替えをしないので、先に並べておくことが要になります。

試した表で取り出せた行は、次のとおりです(売上の単位は万円)。

店舗 上位3件(商品と売上)
本店 マンデリン 90、モカ 80、コロンビア 60
駅前店 モカ 70、キリマンジャロ 55、ブレンド 40

groupbyのheadのしくみ

pandasの資料では、groupbyのheadを、グループごとに最初のn行を返す機能だと説明しています。返すのは元の表の一部の行で、元の行の番号と並びはそのまま残ります。

つまり、headが見るのは「グループの中で表の上にある行」です。売上の大きさは見ないので、売上の大きい順にするのはsort_valuesの役目です。sort_valuesには並べる列を複数渡せ、ascendingで列ごとに小さい順か大きい順かを選べます。

手順: 店舗ごとに上位3件の行を取り出す

次のコードは、架空の表 store_sales.xlsx の「店舗」「商品」「売上」から、店舗ごとに売上の上位3件の行を取り出し、store_top3.xlsx に保存します。元の表には書き込まず、結果は別のファイルにします。

import pandas as pd

# 店舗ごとの売上の表を読む(取り出した行は別のファイルに書く)
table = pd.read_excel("store_sales.xlsx")

# 店舗の中で売上の大きい順に並べ、店舗ごとに先頭から3行を取る
ranked = table.sort_values(["店舗", "売上"], ascending=[True, False])
top3 = ranked.groupby("店舗").head(3)

print(top3)
top3.to_excel("store_top3.xlsx", index=False)

ascendingの[True, False]は、店舗は小さい順、売上は大きい順という指定です。3の数字を変えると、取り出す件数が変わります。

試した結果

本店と駅前店の5件ずつに、店舗の欄が空欄の1件を足した、11行の作り物の表で動かしました。行は店舗が交互になるように並べ、駅前店にはブレンドとマンデリンの2つに同じ40万円を入れました。

  • 取り出した表は6行で、本店・駅前店とも3行ずつ、売上の大きい順に並びました(上の表のとおり)
  • 店舗の欄が空欄だったグアテマラの行は、結果に入りませんでした
  • 取り出した行の番号は、元の表の番号(7、2、9、3、5、1)のままでした
  • store_top3.xlsx には行の番号の列がなく、店舗・商品・売上の3列でした
  • 元の store_sales.xlsx のハッシュ値は、実行の前後で同じでした

使ったのは作業用のMacで、Python 3.12.15にpandas 3.1.0とopenpyxl 3.1.5を入れています。Excelのアプリで開いた見た目は見ていません。

自分で直すか、相談するかの判断

目安は、「何で分けて、何の大きい順に、何件取るか」の3つを言えるかです。「店舗で分けて、売上の大きい順に、3件」と言えれば、上のコードの列の名前と数字を合わせるだけで使えます。

同じ売上が境目に並んだときに何件出すか、店舗が空欄の行をどう扱うかは、報告を受け取る人と先に決めておきます。決まりがないまま件数だけそろえると、毎回ちがう行が残ることがあります。

つまずきやすいところ

  • 並べ替えずにheadを使う: 試したときも、並べ替えを外すと、本店はブレンド50・モカ80・キリマンジャロ30という表の上から3行になり、上位ではありませんでした
  • 境目の同じ売上に気づかない: 駅前店の3位は、ブレンドとマンデリンが同じ40でした。試した表では表で先にあったブレンドが残りましたが、どちらを残すかを決めたいときは、nlargestのkeepや順位の列を使います。同じ値の順位の決め方は、PythonでExcelの表に順位の列を付ける手順で紹介しています
  • 店舗が空欄の行が消える: groupbyは初期設定で、分ける列が空の行を除きます。試したときも、dropna=Falseを付けると、空欄の店舗も1つのグループとして7行になりました
  • 表全体の上位がほしい: 店舗で分けずに上位を出すなら、PythonでExcelの表を並べ替えて上位の行を取り出す手順の方法で足ります
  • 上位の行ではなく、店舗の中の割合を見たい: 店舗の合計に対する割合の列を足す方法は、PythonでExcelのグループごとの割合の列を作る手順にまとめています

まとめ

  • 店舗の中で売上の大きい順に並べてから、groupbyのheadで店舗ごとに先頭の行を取ります
  • headは並べ替えをしないので、並べ替えを忘れると上位ではない行が出ます
  • 境目に同じ売上が並ぶときと、店舗が空欄の行の扱いは、先に決めておきます
  • 保存するときは、index=Falseで行の番号を付けずに書き出します