K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

住所を都道府県・市区町村に分割する

01.7.6

住所を都道府県・市区町村に分割する

最終更新 2020-04-08 読了時間 2 分
まとめ
「東京都千代田区霞が関1-1-1 ○○ビル3F」のような 1 本の住所文字列を、都道府県・市区町村・残りの 3 つに分けます。都道府県は 47 件のリストと startswith で先頭一致させ、市区町村は残りの文字列から「市」「区」「町」「村」が最初に現れる位置までを切り出します。辞書もライブラリも使わない 40 行ほどの関数ですが、地域別の集計や配送エリアの判定に必要な prefecture 列と city 列が得られます。政令指定都市の区や「市川市」のような市名には弱いので、その限界も合わせて確認します。

直感 #

請求書やアンケートの住所は 1 列の文字列として届きますが、集計で欲しいのは「都道府県ごとの件数」や「市区町村ごとの配送コスト」です。住所の先頭は必ず都道府県なので、47 件の一覧と前から比べれば 1 つに決まります。その後ろは「千代田区」「宗像市」のように行政区の名前が「市・区・町・村」のどれかで終わるので、その文字が最初に出た位置で切れば市区町村が取れます。残った「霞が関1-1-1 ○○ビル3F」は番地と建物名で、ここは今回は分けずにそのまま持ちます。

Python で分割する #

次のコードは 47 都道府県のリストを持ち、split_address が prefecture・city・remaining の 3 つのキーを持つ辞書を返します。3 件のサンプルのうち 1 件は政令指定都市の住所で、この関数の限界が見えるようにしてあります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
PREFECTURES = [
    "北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県",
    "茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県",
    "新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県",
    "岐阜県", "静岡県", "愛知県", "三重県",
    "滋賀県", "京都府", "大阪府", "兵庫県", "奈良県", "和歌山県",
    "鳥取県", "島根県", "岡山県", "広島県", "山口県",
    "徳島県", "香川県", "愛媛県", "高知県",
    "福岡県", "佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県",
    "沖縄県",
]

def split_address(address: str) -> dict[str, str]:
    prefecture = ""
    for pref in PREFECTURES:
        if address.startswith(pref):
            prefecture = pref
            break

    rest = address[len(prefecture):]
    city = ""
    for suffix in ("市", "区", "町", "村"):
        if suffix in rest:
            idx = rest.find(suffix)
            city = rest[: idx + 1]
            rest = rest[idx + 1 :]
            break

    return {
        "prefecture": prefecture,
        "city": city,
        "remaining": rest.strip(),
    }

samples = [
    "東京都千代田区霞が関1-1-1 ○○ビル3F",
    "大阪府大阪市北区梅田3丁目1-1",
    "福岡県宗像市田熊4-1-1",
]

for s in samples:
    print(split_address(s))

実行結果の読み方 #

1 件目と 3 件目は意図どおりに city が「千代田区」「宗像市」になります。2 件目の「大阪府大阪市北区梅田3丁目1-1」は city が「大阪市」で止まり、「北区」は remaining の先頭に残ります。政令指定都市を区まで分けたいなら、remaining に対してもう一度「区」で切る処理を足すか、市区町村の一覧との最長一致に切り替えます。都道府県が見つからない住所は prefecture が空文字になるので、== "" でフィルタして件数を確認する習慣をつけてください。

使いどころと落とし穴 #

政令指定都市の区や郡部(「○○郡△△町」)に正しく対応するには、総務省の全国地方公共団体コード(JIS X 0401・X 0402)をダウンロードし、市区町村名の一覧を作ったうえで最長一致に切り替えるのが確実です。この関数は「市」が最初に出た位置で切るので、「千葉県市川市」のように市名の先頭に「市」を含む住所では city が「市」だけになり、一覧との最長一致ならこの誤りは起きません。町名以降の remaining を緯度経度に直したい場合は、geopy や国土地理院のジオコーディング API に prefecture + city + remaining を渡します。郵便番号が付いている住所なら、日本郵便の郵便番号 CSV をマスタにして住所を引き直すと、誤字の修正とローマ字表記の付与も同時に行えます。