LoginSignup
7

More than 1 year has passed since last update.

徳島市ごみ収集日をPandasでデータクレンジングしてCSVに変換

Posted at

を参考に作成

スクレイピング

  • ごみ収集日程表をスクレイピング
import re
import pandas as pd

year = 2022

url = "https://www.city.tokushima.tokushima.jp/smph/kurashi/recycle/gomi/r4gomischedule.html"

# thousandsを設定しないとカンマが消える
dfs = pd.read_html(url, thousands=None)

len(dfs)

データクレンジング

ごみ収集地区割表

  • 五十音順に分割されているのでひとつに結合
def get_area(dfs):

    df0 = pd.concat(dfs).reset_index(drop=True)

    df1 = df0.loc[:, ~df0.columns.str.endswith("")].copy()
    df1["五十音"] = (
        df0.loc[:, df0.columns.str.endswith("")]
        .fillna("")
        .apply(lambda x: "".join(x), axis=1)
    )

    result = df1.reindex(["五十音", "区域", "収集担当", "収集地区"], axis=1)

    return result


area_df = get_area(dfs[:8])
area_df

area_df.to_csv("ごみ収集地区割表.csv", encoding="utf_8_sig")

家庭ごみ収集日程表

  • 燃やせるごみは曜日しかないので曜日から日付を作成
  • 燃やせるごみ以外は月と日が分かれているので結合して日付を作成
# 曜日

subs = {
    "月曜日": "Monday",
    "火曜日": "Tuesday",
    "水曜日": "Wednesday",
    "木曜日": "Thursday",
    "金曜日": "Friday",
    "土曜日": "Saturday",
    "日曜日": "Sunday",
}

# 4/1から3/31までの1年間
dt_range = pd.date_range(f"{year}-04-01", f"{year + 1}-03-31", freq="D")

# 正月三が日
newyear = pd.date_range(f"{year + 1}-01-01", f"{year + 1}-01-03", freq="D")

# 正月三が日を除いた1年間の燃やせるゴミ
calender = pd.DataFrame("燃やせるゴミ", index=dt_range, columns=["分別区分"]).drop(newyear)


def gomi_calender(df0, area):

    df1 = df0.set_index("分別区分").copy()

    # 燃やせるゴミ
    s = df1.iat[0, 0]

    # 曜日抽出
    youbi = re.findall("[月火水木金土日]曜日", s)

    # 曜日を英語に変換
    weekday = [subs.get(i, i) for i in youbi]

    # 指定曜日を抽出
    df2 = calender[calender.index.day_name().isin(weekday)].copy().reset_index()
    df3 = df2.rename(columns={"index": "日付"})

    # 燃やせるごみ以外
    df4 = df1.iloc[1:].stack().reset_index()
    df4.set_axis(["分別区分", "month", "day"], axis=1, inplace=True)

    # 月
    df4["month"] = df4["month"].str.rstrip("").astype(int)

    # 複数日を分解
    df4["day"] = df4["day"].str.split(",")
    df5 = df4.explode("day").reset_index(drop=True)
    df5["day"] = df5["day"].astype(int)

    # 年
    df5["year"] = year

    # 1~3月は年 +1
    df5["year"].mask(df5["month"] < 4, df5["year"] + 1, inplace=True)

    # 年月日から日付に変換
    df5["日付"] = pd.to_datetime(df5[["year", "month", "day"]])

    df6 = df5.reindex(["日付", "分別区分"], axis=1)

    # 結合
    result = pd.concat([df3, df6]).reset_index(drop=True)
    result.to_csv(f"{area}.csv", encoding="utf_8_sig")

    result["収集地区"] = area

    return result


data = []

for df, area in zip(dfs[8:], ["A地区", "B地区", "C地区", "D地区"]):

    data.append(gomi_calender(df, area))

result = pd.concat(data).reset_index(drop=True)

result

result.to_csv("家庭ごみ収集日程表全データ.csv", encoding="utf_8_sig")

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7