【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()を組み合わせてフィルタリングしています。行数の多い大規模なデータセットでは、ループを回すよりもこちらの方が可読性・パフォーマンスの両面で有利です。
-
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を指定して呼び出します。これにより、要素が降順に並べ替
-
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()メソッドでインデックスと値を順番に取り