Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import re
- from pathlib import Path
- import numpy as np
- import pandas as pd
- import matplotlib.pyplot as plt
- DATA_PATH = Path("VRP_ reg_04_20_II_ue.xlsx")
- OUT_DIR = Path("lab1_outputs")
- OUT_DIR.mkdir(exist_ok=True, parents=True)
- def find_per_capita_table(df_all, section_text):
- pos = None
- for r in range(df_all.shape[0]):
- for c in range(df_all.shape[1]):
- v = df_all.iat[r, c]
- if isinstance(v, str) and section_text.lower() in v.lower():
- pos = (r, c)
- break
- if pos:
- break
- if pos is None:
- raise RuntimeError("Секцію не знайдено.")
- r0, c0 = pos
- r_hdr = r0 + 1
- row_hdr_vals = df_all.iloc[r_hdr, :]
- year_map = {}
- for c in range(df_all.shape[1]):
- v = row_hdr_vals[c]
- if pd.isna(v):
- continue
- try:
- iv = int(float(v))
- if 2000 <= iv <= 2100:
- year_map.setdefault(iv, c)
- continue
- except Exception:
- pass
- if isinstance(v, str):
- m = re.search(r"(20\d{2})", v)
- if m:
- iv = int(m.group(1))
- if 2000 <= iv <= 2100:
- year_map.setdefault(iv, c)
- needed_years = [2017, 2018, 2019]
- missing = [y for y in needed_years if y not in year_map]
- if missing:
- raise RuntimeError(f"Не знайдено колонки для років: {missing}")
- c_region = 0
- r_data_start = r_hdr + 1
- rows = []
- for r in range(r_data_start, df_all.shape[0]):
- name = df_all.iat[r, c_region]
- if not isinstance(name, str) or name.strip() == "":
- if r + 1 < df_all.shape[0]:
- name2 = df_all.iat[r + 1, c_region]
- if (not isinstance(name2, str)) or name2.strip() == "":
- break
- continue
- rec = {"Область": name.replace("\\n", " ").strip()}
- for y in needed_years:
- c = year_map[y]
- rec[str(y)] = df_all.iat[r, c]
- rows.append(rec)
- raw_df = pd.DataFrame(rows)
- bad_keywords = ["україна", "області", "всього", "усього", "разом"]
- mask_bad = raw_df["Область"].str.lower().apply(lambda s: any(k in s for k in bad_keywords))
- clean_df = raw_df[~mask_bad].copy().reset_index(drop=True)
- for y in needed_years:
- clean_df[str(y)] = pd.to_numeric(clean_df[str(y)], errors="coerce")
- return clean_df[["Область", "2017", "2018", "2019"]]
- def descriptive_stats(series: pd.Series):
- s = series.dropna()
- out = {
- "count": s.count(),
- "mean": s.mean(),
- "variance": s.var(ddof=1),
- "std": s.std(ddof=1),
- "median": s.median(),
- "min": s.min(),
- "max": s.max(),
- "range": s.max() - s.min(),
- "skewness": s.skew(),
- "excess_kurtosis": s.kurt(),
- }
- try:
- mode_vals = s.mode(dropna=True)
- out["mode"] = mode_vals.iloc[0] if len(mode_vals) > 0 else np.nan
- except Exception:
- out["mode"] = np.nan
- return out
- def plot_hist_and_polygon(values: pd.Series, year: str, out_dir: Path, bins: int = None):
- s = values.dropna()
- if bins is None:
- n = len(s)
- bins = int(np.ceil(np.log2(n) + 1)) if n > 0 else 10
- plt.figure()
- plt.hist(s.values, bins=bins, edgecolor="black")
- plt.title(f"Гістограма: ВРП на душу населення, {year}")
- plt.xlabel("грн на особу")
- plt.ylabel("К-сть областей")
- out_hist = out_dir / f"hist_{year}.png"
- plt.tight_layout()
- plt.savefig(out_hist, dpi=150)
- plt.close()
- counts, edges = np.histogram(s.values, bins=bins)
- mids = 0.5 * (edges[1:] + edges[:-1])
- plt.figure()
- plt.plot(mids, counts, marker="o")
- plt.title(f"Полігон частот: ВРП на душу населення, {year}")
- plt.xlabel("грн на особу")
- plt.ylabel("К-сть областей")
- out_poly = out_dir / f"polygon_{year}.png"
- plt.tight_layout()
- plt.savefig(out_poly, dpi=150)
- plt.close()
- return out_hist, out_poly
- if __name__ == "__main__":
- import pandas as pd
- df_all = pd.read_excel(DATA_PATH, sheet_name="Лист1", header=None)
- section_text = "Валовий регіональний продукт у розрахунку на одну особу"
- df = find_per_capita_table(df_all, section_text)
- out_csv = OUT_DIR / "vrp_per_capita_clean_2017_2019.csv"
- df.to_csv(out_csv, index=False)
- years = ["2017","2018","2019"]
- stats = []
- for y in years:
- st = descriptive_stats(df[y])
- st["year"] = y
- stats.append(st)
- combined_series = pd.concat([df[y] for y in years], ignore_index=True)
- st_all = descriptive_stats(combined_series)
- st_all["year"] = "2017-2019 (загалом)"
- stats.append(st_all)
- stats_df = pd.DataFrame(stats)[["year","count","mean","variance","std","mode","median","min","max","range","skewness","excess_kurtosis"]]
- stats_path = OUT_DIR / "descriptive_stats_2017_2019.csv"
- stats_df.to_csv(stats_path, index=False)
- import numpy as np
- import matplotlib.pyplot as plt
- years = ["2017","2018","2019"]
- series_list = [df[y].dropna().values for y in years]
- combined = np.concatenate(series_list)
- n = len(combined)
- bins = int(np.ceil(np.log2(n) + 1)) if n > 0 else 10
- _, edges = np.histogram(combined, bins=bins)
- plt.figure()
- for s, y in zip(series_list, years):
- plt.hist(s, bins=edges, alpha=0.3, label=y, edgecolor="black")
- plt.title("Гістограма: ВРП на душу населення, 2017–2019")
- plt.xlabel("грн на особу")
- plt.ylabel("К-сть областей")
- plt.legend(title="Рік")
- (OUT_DIR / "plots").mkdir(exist_ok=True, parents=True)
- plt.tight_layout()
- plt.savefig(OUT_DIR / "plots" / "hist_all_years.png", dpi=150)
- plt.close()
- mids = 0.5 * (edges[1:] + edges[:-1])
- plt.figure()
- for s, y in zip(series_list, years):
- c, _ = np.histogram(s, bins=edges)
- plt.plot(mids, c, marker="o", alpha=0.7, label=y)
- plt.title("Полігон частот: ВРП на душу населення, 2017–2019")
- plt.xlabel("грн на особу")
- plt.ylabel("К-сть областей")
- plt.legend(title="Рік")
- plt.tight_layout()
- plt.savefig(OUT_DIR / "plots" / "polygon_all_years.png", dpi=150)
- plt.close()
- plt.figure()
- plt.hist(combined, bins=edges, edgecolor="black")
- plt.title("Гістограма: ВРП на душу населення, 2017–2019 (загалом)")
- plt.xlabel("грн на особу")
- plt.ylabel("К-сть областей")
- plt.tight_layout()
- plt.savefig(OUT_DIR / "plots" / "hist_total_2017_2019.png", dpi=150)
- plt.close()
- c_total, _ = np.histogram(combined, bins=edges)
- plt.figure()
- plt.plot(mids, c_total, marker="o")
- plt.title("Полігон частот: ВРП на душу населення, 2017–2019 (загалом)")
- plt.xlabel("грн на особу")
- plt.ylabel("К-сть областей")
- plt.tight_layout()
- plt.savefig(OUT_DIR / "plots" / "polygon_total_2017_2019.png", dpi=150)
- plt.close()
- out_xlsx = OUT_DIR / "ugrupuvannia_vrp_2017_2019.xlsx"
- with pd.ExcelWriter(out_xlsx, engine="xlsxwriter") as writer:
- for y in years:
- s = df[["Область", y]].dropna().copy()
- labels_q = ["Q1 (низький)", "Q2", "Q3", "Q4 (високий)"]
- try:
- s["Група_квартилі"] = pd.qcut(s[y], 4, labels=labels_q)
- except ValueError:
- s["Група_квартилі"] = pd.qcut(s[y].rank(method="average"), 4, labels=labels_q)
- n = s[y].notna().sum()
- bins = int(np.ceil(np.log2(n) + 1)) if n > 0 else 5
- s["Група_інтервали"] = pd.cut(s[y], bins=bins, include_lowest=True)
- s.sort_values(y).to_excel(writer, sheet_name=f"{y}_деталі", index=False)
- s["Група_квартилі"].value_counts().sort_index().rename("К-сть областей").to_frame().to_excel(writer, sheet_name=f"{y}_квартилі")
- s["Група_інтервали"].value_counts().sort_index().rename("К-сть областей").to_frame().to_excel(writer, sheet_name=f"{y}_інтервали")
- print("Очищені дані:", out_csv)
- print("Статистика:", stats_path)
- print("Угрупування:", out_xlsx)
- print("Графіки:", OUT_DIR / "plots")
Advertisement
Add Comment
Please, Sign In to add comment