mirosh111000

Прикладна_економетрика_ЛР№1_Мірошниченко

Sep 15th, 2025
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.74 KB | None | 0 0
  1. import re
  2. from pathlib import Path
  3. import numpy as np
  4. import pandas as pd
  5. import matplotlib.pyplot as plt
  6.  
  7. DATA_PATH = Path("VRP_ reg_04_20_II_ue.xlsx")
  8. OUT_DIR = Path("lab1_outputs")
  9. OUT_DIR.mkdir(exist_ok=True, parents=True)
  10.  
  11. def find_per_capita_table(df_all, section_text):
  12.     pos = None
  13.     for r in range(df_all.shape[0]):
  14.         for c in range(df_all.shape[1]):
  15.             v = df_all.iat[r, c]
  16.             if isinstance(v, str) and section_text.lower() in v.lower():
  17.                 pos = (r, c)
  18.                 break
  19.         if pos:
  20.             break
  21.     if pos is None:
  22.         raise RuntimeError("Секцію не знайдено.")
  23.     r0, c0 = pos
  24.  
  25.     r_hdr = r0 + 1
  26.     row_hdr_vals = df_all.iloc[r_hdr, :]
  27.  
  28.     year_map = {}
  29.     for c in range(df_all.shape[1]):
  30.         v = row_hdr_vals[c]
  31.         if pd.isna(v):
  32.             continue
  33.         try:
  34.             iv = int(float(v))
  35.             if 2000 <= iv <= 2100:
  36.                 year_map.setdefault(iv, c)
  37.                 continue
  38.         except Exception:
  39.             pass
  40.         if isinstance(v, str):
  41.             m = re.search(r"(20\d{2})", v)
  42.             if m:
  43.                 iv = int(m.group(1))
  44.                 if 2000 <= iv <= 2100:
  45.                     year_map.setdefault(iv, c)
  46.  
  47.     needed_years = [2017, 2018, 2019]
  48.     missing = [y for y in needed_years if y not in year_map]
  49.     if missing:
  50.         raise RuntimeError(f"Не знайдено колонки для років: {missing}")
  51.  
  52.     c_region = 0
  53.     r_data_start = r_hdr + 1
  54.     rows = []
  55.     for r in range(r_data_start, df_all.shape[0]):
  56.         name = df_all.iat[r, c_region]
  57.         if not isinstance(name, str) or name.strip() == "":
  58.             if r + 1 < df_all.shape[0]:
  59.                 name2 = df_all.iat[r + 1, c_region]
  60.                 if (not isinstance(name2, str)) or name2.strip() == "":
  61.                     break
  62.             continue
  63.         rec = {"Область": name.replace("\\n", " ").strip()}
  64.         for y in needed_years:
  65.             c = year_map[y]
  66.             rec[str(y)] = df_all.iat[r, c]
  67.         rows.append(rec)
  68.     raw_df = pd.DataFrame(rows)
  69.  
  70.     bad_keywords = ["україна", "області", "всього", "усього", "разом"]
  71.     mask_bad = raw_df["Область"].str.lower().apply(lambda s: any(k in s for k in bad_keywords))
  72.     clean_df = raw_df[~mask_bad].copy().reset_index(drop=True)
  73.     for y in needed_years:
  74.         clean_df[str(y)] = pd.to_numeric(clean_df[str(y)], errors="coerce")
  75.  
  76.     return clean_df[["Область", "2017", "2018", "2019"]]
  77.  
  78. def descriptive_stats(series: pd.Series):
  79.     s = series.dropna()
  80.     out = {
  81.         "count": s.count(),
  82.         "mean": s.mean(),
  83.         "variance": s.var(ddof=1),
  84.         "std": s.std(ddof=1),
  85.         "median": s.median(),
  86.         "min": s.min(),
  87.         "max": s.max(),
  88.         "range": s.max() - s.min(),
  89.         "skewness": s.skew(),
  90.         "excess_kurtosis": s.kurt(),
  91.     }
  92.     try:
  93.         mode_vals = s.mode(dropna=True)
  94.         out["mode"] = mode_vals.iloc[0] if len(mode_vals) > 0 else np.nan
  95.     except Exception:
  96.         out["mode"] = np.nan
  97.     return out
  98.  
  99. def plot_hist_and_polygon(values: pd.Series, year: str, out_dir: Path, bins: int = None):
  100.     s = values.dropna()
  101.     if bins is None:
  102.         n = len(s)
  103.         bins = int(np.ceil(np.log2(n) + 1)) if n > 0 else 10
  104.  
  105.     plt.figure()
  106.     plt.hist(s.values, bins=bins, edgecolor="black")
  107.     plt.title(f"Гістограма: ВРП на душу населення, {year}")
  108.     plt.xlabel("грн на особу")
  109.     plt.ylabel("К-сть областей")
  110.     out_hist = out_dir / f"hist_{year}.png"
  111.     plt.tight_layout()
  112.     plt.savefig(out_hist, dpi=150)
  113.     plt.close()
  114.  
  115.     counts, edges = np.histogram(s.values, bins=bins)
  116.     mids = 0.5 * (edges[1:] + edges[:-1])
  117.     plt.figure()
  118.     plt.plot(mids, counts, marker="o")
  119.     plt.title(f"Полігон частот: ВРП на душу населення, {year}")
  120.     plt.xlabel("грн на особу")
  121.     plt.ylabel("К-сть областей")
  122.     out_poly = out_dir / f"polygon_{year}.png"
  123.     plt.tight_layout()
  124.     plt.savefig(out_poly, dpi=150)
  125.     plt.close()
  126.     return out_hist, out_poly
  127.  
  128. if __name__ == "__main__":
  129.     import pandas as pd
  130.     df_all = pd.read_excel(DATA_PATH, sheet_name="Лист1", header=None)
  131.     section_text = "Валовий регіональний продукт  у розрахунку на одну особу"
  132.     df = find_per_capita_table(df_all, section_text)
  133.  
  134.     out_csv = OUT_DIR / "vrp_per_capita_clean_2017_2019.csv"
  135.     df.to_csv(out_csv, index=False)
  136.  
  137.     years = ["2017","2018","2019"]
  138.  
  139.     stats = []
  140.     for y in years:
  141.         st = descriptive_stats(df[y])
  142.         st["year"] = y
  143.         stats.append(st)
  144.  
  145.     combined_series = pd.concat([df[y] for y in years], ignore_index=True)
  146.     st_all = descriptive_stats(combined_series)
  147.     st_all["year"] = "2017-2019 (загалом)"
  148.     stats.append(st_all)
  149.  
  150.     stats_df = pd.DataFrame(stats)[["year","count","mean","variance","std","mode","median","min","max","range","skewness","excess_kurtosis"]]
  151.     stats_path = OUT_DIR / "descriptive_stats_2017_2019.csv"
  152.     stats_df.to_csv(stats_path, index=False)
  153.  
  154.     import numpy as np
  155.     import matplotlib.pyplot as plt
  156.  
  157.     years = ["2017","2018","2019"]
  158.     series_list = [df[y].dropna().values for y in years]
  159.     combined = np.concatenate(series_list)
  160.     n = len(combined)
  161.     bins = int(np.ceil(np.log2(n) + 1)) if n > 0 else 10
  162.     _, edges = np.histogram(combined, bins=bins)
  163.  
  164.     plt.figure()
  165.     for s, y in zip(series_list, years):
  166.         plt.hist(s, bins=edges, alpha=0.3, label=y, edgecolor="black")
  167.     plt.title("Гістограма: ВРП на душу населення, 2017–2019")
  168.     plt.xlabel("грн на особу")
  169.     plt.ylabel("К-сть областей")
  170.     plt.legend(title="Рік")
  171.     (OUT_DIR / "plots").mkdir(exist_ok=True, parents=True)
  172.     plt.tight_layout()
  173.     plt.savefig(OUT_DIR / "plots" / "hist_all_years.png", dpi=150)
  174.     plt.close()
  175.  
  176.     mids = 0.5 * (edges[1:] + edges[:-1])
  177.     plt.figure()
  178.     for s, y in zip(series_list, years):
  179.         c, _ = np.histogram(s, bins=edges)
  180.         plt.plot(mids, c, marker="o", alpha=0.7, label=y)
  181.     plt.title("Полігон частот: ВРП на душу населення, 2017–2019")
  182.     plt.xlabel("грн на особу")
  183.     plt.ylabel("К-сть областей")
  184.     plt.legend(title="Рік")
  185.     plt.tight_layout()
  186.     plt.savefig(OUT_DIR / "plots" / "polygon_all_years.png", dpi=150)
  187.     plt.close()
  188.  
  189.     plt.figure()
  190.     plt.hist(combined, bins=edges, edgecolor="black")
  191.     plt.title("Гістограма: ВРП на душу населення, 2017–2019 (загалом)")
  192.     plt.xlabel("грн на особу")
  193.     plt.ylabel("К-сть областей")
  194.     plt.tight_layout()
  195.     plt.savefig(OUT_DIR / "plots" / "hist_total_2017_2019.png", dpi=150)
  196.     plt.close()
  197.  
  198.     c_total, _ = np.histogram(combined, bins=edges)
  199.     plt.figure()
  200.     plt.plot(mids, c_total, marker="o")
  201.     plt.title("Полігон частот: ВРП на душу населення, 2017–2019 (загалом)")
  202.     plt.xlabel("грн на особу")
  203.     plt.ylabel("К-сть областей")
  204.     plt.tight_layout()
  205.     plt.savefig(OUT_DIR / "plots" / "polygon_total_2017_2019.png", dpi=150)
  206.     plt.close()
  207.  
  208.     out_xlsx = OUT_DIR / "ugrupuvannia_vrp_2017_2019.xlsx"
  209.     with pd.ExcelWriter(out_xlsx, engine="xlsxwriter") as writer:
  210.         for y in years:
  211.             s = df[["Область", y]].dropna().copy()
  212.             labels_q = ["Q1 (низький)", "Q2", "Q3", "Q4 (високий)"]
  213.             try:
  214.                 s["Група_квартилі"] = pd.qcut(s[y], 4, labels=labels_q)
  215.             except ValueError:
  216.                 s["Група_квартилі"] = pd.qcut(s[y].rank(method="average"), 4, labels=labels_q)
  217.  
  218.             n = s[y].notna().sum()
  219.             bins = int(np.ceil(np.log2(n) + 1)) if n > 0 else 5
  220.             s["Група_інтервали"] = pd.cut(s[y], bins=bins, include_lowest=True)
  221.  
  222.             s.sort_values(y).to_excel(writer, sheet_name=f"{y}_деталі", index=False)
  223.             s["Група_квартилі"].value_counts().sort_index().rename("К-сть областей").to_frame().to_excel(writer, sheet_name=f"{y}_квартилі")
  224.             s["Група_інтервали"].value_counts().sort_index().rename("К-сть областей").to_frame().to_excel(writer, sheet_name=f"{y}_інтервали")
  225.  
  226.     print("Очищені дані:", out_csv)
  227.     print("Статистика:", stats_path)
  228.     print("Угрупування:", out_xlsx)
  229.     print("Графіки:", OUT_DIR / "plots")
  230.  
Advertisement
Add Comment
Please, Sign In to add comment