単元 8:重複・並べ替え
duplicated()で重複行を検出できるdrop_duplicates()で重複行を除去できる(保持する行を選べる)sort_values()で 1 列・複数列で並べ替えられる- 昇順/降順、欠損値の扱い方を指定できる
重複と並べ替えは「データの整え」の仕上げ
Section titled “重複と並べ替えは「データの整え」の仕上げ”前単元までで「欠損」「型」「列の編集」を整えました。集計や可視化に進む前の仕上げとして、重複の除去 と 並べ替え を行います。
- 重複 — 同じレコードが 2 回以上記録されていると、件数も平均もずれます。データ収集の不備や結合ミスで発生しがち
- 並べ替え — 表を「最新順」「金額の高い順」など、人や次の処理が見やすい順序に並べることで、要約や上位抽出が簡単になります
どちらも 1 メソッドで完結する操作ですが、何を基準にするか の決定が重要です。
重複を検出する
Section titled “重複を検出する”duplicated() は 「上から見て同じ行が出てきたら True」 を返します:
df.duplicated() # 各行が重複かどうかを Series で返すdf.duplicated().sum() # 重複行の数df[df.duplicated()] # 重複行だけを抽出デフォルトでは 全列が一致する行 を重複と見なします。「氏名と生年月日だけで判定したい」場合は subset を指定:
df.duplicated(subset=["氏名", "生年月日"])重複を除去する
Section titled “重複を除去する”drop_duplicates() は重複行を取り除きます。デフォルトでは 「最初に出てきた行を残す」 挙動です:
df.drop_duplicates()df.drop_duplicates(subset=["氏名", "生年月日"])「最後に出てきた行を残したい」場合は keep="last" を、「重複したらすべて落としたい」場合は keep=False を指定します:
df.drop_duplicates(keep="last") # 最後を残すdf.drop_duplicates(keep=False) # 重複したものは全部落とすたとえば「同じ顧客の最新の購入記録だけ残したい」なら、日付で並べ替えてから keep="last"、というパターンになります。
並べ替えの基本
Section titled “並べ替えの基本”sort_values() は指定列で並べ替えます:
df.sort_values("年齢") # 昇順(小さい順)df.sort_values("年齢", ascending=False) # 降順(大きい順)文字列の列でも使えますが、辞書順(A, B, C, … a, b, c, … 日本語は文字コード順)になる点に注意。意図した順序にならないことがあります。
複数列での並べ替え
Section titled “複数列での並べ替え”「都市で並べた上で、同じ都市内では年齢が高い順」のような複合的な並べ替えはリストで指定:
df.sort_values( by=["都市", "年齢"], ascending=[True, False], # 都市は昇順、年齢は降順)ascending をリストで渡すと、列ごとに昇順/降順を変えられます。
欠損値の扱い
Section titled “欠損値の扱い”並べ替えで欠損値(NaN)がどこに来るかは指定できます:
df.sort_values("年齢", na_position="last") # 既定:欠損を末尾にdf.sort_values("年齢", na_position="first") # 欠損を先頭に意外と気付かないですが、欠損値の位置で上位抽出(head(10))の結果が変わります。
インデックスの並べ替え
Section titled “インデックスの並べ替え”「値ではなくインデックスで並べる」場合は sort_index():
df.sort_index() # 行インデックスで並べ替えdf.sort_index(axis=1) # 列名で並べ替え時系列データを「日付順」に戻したいときによく使います。
並べ替えと「上位抽出」のセット
Section titled “並べ替えと「上位抽出」のセット”sort_values() の結果に head() を続ければ、「上位 N 件」を簡単に取り出せます:
df.sort_values("収入", ascending=False).head(10) # 収入が高い順 10 件df.sort_values("年齢").head(5) # 年齢が低い順 5 件このパターンは集計の前段としても、最終結果のレポートとしても頻出します。
よく出る躓きどころ
Section titled “よく出る躓きどころ”- 重複判定で
subsetを指定し忘れる — 全列一致を見るので、付随情報が少し違うだけで「重複」と認識されない drop_duplicates()の戻り値を変数に代入し忘れる — pandas のメソッドは原則「新しい DataFrame を返す」。df.drop_duplicates()を呼んだだけではdfは変わらない。df = df.drop_duplicates()と代入し直す- 文字列の並べ替えが意図と異なる — 辞書順なので「10、2、3」が「10、2、3」のままになる(数値ソートではない)。事前に型を直すか、
str.zfill()で桁数を揃える - 欠損値の位置を考慮せずに上位抽出 —
na_positionの指定で結果が変わる
サンプルコード
Section titled “サンプルコード”- 題材データ:users.csv をダウンロード
users.csv を題材に、次を順に行いなさい。
df.duplicated().sum()で重複の有無を確認する年齢列で降順に並べ替えて、上位 3 件を表示する都市昇順・年齢降順の組み合わせで並べ替える- 「同じ氏名は 1 行だけ残す」前提で
drop_duplicates(subset=["名前"])を実行し、行数の変化を確認する
drop_duplicates() の結果を df に代入し直すと、以降の操作にも反映されることが体感できます。
発展課題(オプション)
Section titled “発展課題(オプション)”sort_valuesのkey引数を使って、文字列を小文字化してから並べ替える- 時系列風のデータを作り、
sort_indexで日付順に戻してからhead()で「最初の数日」を取り出す duplicated()にkeep=Falseを指定し、「2 回以上現れる行を全部抽出」して可視化する