Python
 Computer >> コンピューター >  >> プログラミング >> Python

【Python】データフレームのCity列から頭文字が重複する都市だけを抽出・フィルタリングする方法


Pandasのデータフレームを扱っていると、「City列に含まれる都市名のうち、先頭文字(イニシャル)がほかの行と重複しているものだけを抽出したい」という要件に出会うことがあります。本記事では、Pythonを使ってこのフィルタリング処理を実装する具体的な手順を、サンプルコード付きでわかりやすく解説します。

ゴールとなる出力

処理後のデータフレームは次のようになります。頭文字が2回以上登場する都市(Kolkata・Hyderabad・Haryana・Kakinada・Kochin)だけが残り、頭文字が一意な都市は除外されます。

   Id       City
2   3    Kolkata
3   4  Hyderabad
6   7    Haryana
8   9   Kakinada
9  10     Kochin

解決のための手順

以下のステップに沿って実装していきます。

ステップ1:データフレームを定義する

まず、サンプルとなるデータフレームを作成します。

import pandas as pd

df = pd.DataFrame({'Id':[1,2,3,4,5,6,7,8,9,10],
                   'City':['Chennai','Delhi','Kolkata','Hyderabad','Pune',
                           'Mumbai','Haryana','Bengaluru','Kakinada','Kochin']
                  })

ステップ2:City列の先頭文字をすべて取得する

空のリストを用意し、City列の各要素の最初の1文字を順番に追加していきます。

l = []
for x in df['City']:
    l.append(x[0])

この時点で、リストlには ['C', 'D', 'K', 'H', 'P', 'M', 'H', 'B', 'K', 'K'] という先頭文字の一覧が格納されています。

ステップ3:重複している先頭文字だけを抽出する

次に、もうひとつの空のリストを用意します。forループとif文を組み合わせて、出現回数が2回以上の文字だけを追加します。

l1 = []
for j in l:
    if(l.count(j) > 1):
        if(j not in l1):
            l1.append(j)

ポイントは「j not in l1」という条件です。これにより同じ文字が二重に追加されるのを防ぎます。結果として、l1には重複している頭文字である ['K', 'H'] のみが格納されます。

ステップ4:該当する都市名を抽出する

さらに空のリストを作成し、City列の各要素について「先頭文字がl1に含まれているか」を判定します。条件を満たす都市名だけを新しいリストに追加していきます。

l2 = []
for x in df['City']:
    if(x[0] in l1):
        l2.append(x)

ステップ5:isin()でデータフレームをフィルタリングする

最後に、抽出したリストl2の要素がCity列に存在するかどうかをisin()で確認し、条件に一致する行だけを出力します。

df[df['City'].isin(l2)]

完全なサンプルコード

理解を深めるために、ここまでの手順をまとめたコード全体を見てみましょう。

import pandas as pd

df = pd.DataFrame({'Id':[1,2,3,4,5,6,7,8,9,10],
                   'City':['Chennai','Delhi','Kolkata','Hyderabad','Pune',
                           'Mumbai','Haryana','Bengaluru','Kakinada','Kochin']
                  })

# 先頭文字をすべて取得
l = []
for x in df['City']:
    l.append(x[0])

# 重複している先頭文字のみ抽出
l1 = []
for j in l:
    if(l.count(j) > 1):
        if(j not in l1):
            l1.append(j)

# 該当する都市名を抽出
l2 = []
for x in df['City']:
    if(x[0] in l1):
        l2.append(x)

print(df[df['City'].isin(l2)])

実行結果

   Id       City
2   3    Kolkata
3   4  Hyderabad
6   7    Haryana
8   9   Kakinada
9  10     Kochin

補足:リスト内包表記とCounterでより簡潔に書く

よりPythonらしい書き方としては、collections.Counterを使えばコードを大幅に短縮できます。

from collections import Counter

counts = Counter(df['City'].str[0])
duplicated = {c for c, n in counts.items() if n > 1}
result = df[df['City'].str[0].isin(duplicated)]
print(result)

Counterで先頭文字の出現回数を一括集計し、2回以上出現する文字の集合を作成したあと、str[0]とisin()を組み合わせてフィルタリングしています。行数の多い大規模なデータセットでは、ループを回すよりもこちらの方が可読性・パフォーマンスの両面で有利です。

  1. PythonでSeries(シリーズ)の全要素を降順にソートする方法

    はじめにこの記事では、Pythonのpandasライブラリを使用して、Series(シリーズ)内のすべての要素を降順で並べ替える方法を解説します。入力例:次のようなSeriesがあると仮定します。0 abdef 1 ijkl 2 Abdef 3 oUijl出力例:すべての要素を降順に並べ替えると、結果は以下のようになります。3 oUijl 1 ijkl 0 abdef 2 Abdef解決手順この問題を解決するには、以下の手順に従います。まず、Seriesを定義します。sort_valuesメソッドに対して、引数ascending=Falseを指定して呼び出します。これにより、要素が降順に並べ替

  2. PythonでpandasのSeriesから整数要素のみを抽出・フィルタリングする方法

    文字列と整数が混在するpandasのSeriesから、整数要素のみを抽出する方法を、2つの異なるアプローチで解説します。 入力データと期待される出力 入力 ― 次のようなSeriesを想定します。 0 1 1 2 2 python 3 pandas 4 3 5 4 6 5 出力 ― 整数要素のみを抽出した結果は以下の通りです。 0 1 1 2 4 3 5 4 6 5 解法1:type()でデータ型を判定する pandasのSeriesを定義します。 forループとitems()メソッドでインデックスと値を順番に取り