โ‘  ์žฌ์ •ํŒจ๋„ ์†Œ๋“๋ถ„์œ„๋ณ„ ๊ฐ€์ •์šฉ ์ฃผ๋ฅ˜์ง€์ถœ โ€” ์—ญ์ง„์„ฑ ํŒจ๋„ยถ

์ฃผ์„ธ ์ •์ฑ…์ด ๊ฒฝ์ œยท๋ฏผ์ƒ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ ์—ฐ๊ตฌ ยท ์žฌ์ •ํŒจ๋„(NaSTaB) 1~17์ฐจ(2008~2024) ๊ฐ€๊ตฌ๋ฐ์ดํ„ฐ

๊ฐ€์ •์šฉ ์ฃผ๋ฅ˜๋น„ = cd002(๋งฅ์ฃผยท์†Œ์ฃผยท์–‘์ฃผ) + cd004(์™€์ธยท๋ง‰๊ฑธ๋ฆฌยท์ „ํ†ต์ฃผ), ์›”ํ‰๊ท  ๋งŒ์›. ๊ฐ€๊ตฌ ํšก๋‹จ๊ฐ€์ค‘์น˜ h{์ฐจ}cwt ์ ์šฉ. ๊ฒฐ์ธก(-9 ๋“ฑ) ์ œ์™ธ, ๋ฏธ๊ตฌ์ž…=0.

์›์ž๋ฃŒ๋Š” KIPF ์‹ ์ฒญยท๋‹ค์šด๋กœ๋“œ๋ถ„์ด๋ฉฐ ๊ณต๊ฐœ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋‹ค. ๋ณธ ๋…ธํŠธ๋ถ์€ ์žฌํ˜„ ์ ˆ์ฐจ ๋ฌธ์„œ์šฉ์ด๋‹ค.

Inย [1]:
import pandas as pd, numpy as np, csv, os
D=r"D:\Project\2026_2\์ฃผ๋ฅ˜์„ธ\data\nastab"; OUT=r"D:\Project\2026_2\์ฃผ๋ฅ˜์„ธ\data"
MISS={-1,-9,-8,-99,-999,999999}
def wcols(ww):
    with open(os.path.join(D,f"NaSTaB{ww}H.csv"),encoding="utf-8-sig") as f: return set(next(csv.reader(f)))
def weighted_decile(vals,wts):
    d=pd.DataFrame({"v":pd.to_numeric(vals,errors="coerce"),"w":pd.to_numeric(wts,errors="coerce")},index=vals.index)
    d=d[d["v"].notna()&d["w"].notna()&(d["w"]>0)].sort_values("v")
    cw=d["w"].cumsum(); frac=(cw-d["w"]*0.5)/d["w"].sum()
    d["dec"]=np.clip(np.ceil(frac*10),1,10).astype(int)
    return d["dec"].reindex(vals.index)
def wmean(x,w):
    m=x.notna()&w.notna()
    return np.average(x[m],weights=w[m]) if (m.sum() and w[m].sum()) else np.nan

17๊ฐœ ์ฐจ์ˆ˜ ์ˆœํšŒ โ€” ์†Œ๋“๋ถ„์œ„๋ณ„ ๋น„์ค‘ ์‚ฐ์ถœยถ

Inย [2]:
rows=[]
for w in range(1,18):
    ww=f"{w:02d}"; have=wcols(ww)
    inc=f"h{ww}ca004" if f"h{ww}ca004" in have else None
    con=f"h{ww}ca002"; cd2=f"h{ww}cd002"; cd4=f"h{ww}cd004"
    wt=f"h{ww}cwt" if f"h{ww}cwt" in have else None
    use=[c for c in [inc,con,cd2,cd4,wt] if c]
    df=pd.read_csv(os.path.join(D,f"NaSTaB{ww}H.csv"),usecols=use,encoding="utf-8-sig")
    for c in use: df[c]=pd.to_numeric(df[c],errors="coerce")
    if inc: df[inc]=df[inc].where(~df[inc].isin(MISS)).where(df[inc]>0)
    df[con]=df[con].where(~df[con].isin(MISS)).where(df[con]>0)
    for c in [cd2,cd4]: df[c]=df[c].where(~df[c].isin(MISS))
    W=df[wt] if wt else pd.Series(1.0,index=df.index)
    alc=df[cd2].fillna(0)+df[cd4].fillna(0)
    rec={"wave":w,"survey_year":2007+w,"n":len(df),
         "alc_share_con_pct_all":round(wmean(alc,W)/wmean(df[con],W)*100,3),
         "purchase_rate_pct":round(wmean((alc>0).astype(float),W)*100,1)}
    if inc:
        sub=df[df[inc].notna()].copy(); sub["dec"]=weighted_decile(sub[inc],W[sub.index])
        for d in range(1,11):
            g=sub[sub["dec"]==d]; a=wmean(alc[g.index],W[g.index]); c=wmean(g[con],W[g.index])
            rec[f"D{d:02d}_alc_con_pct"]=round(a/c*100,3) if c else np.nan
    rows.append(rec)
res=pd.DataFrame(rows); res.to_csv(os.path.join(OUT,"nastab_alcohol_panel.csv"),index=False,encoding="utf-8-sig")
print("์™„๋ฃŒ:",len(res),"๊ฐœ ์ฐจ์ˆ˜")
์™„๋ฃŒ: 17 ๊ฐœ ์ฐจ์ˆ˜

๊ฒฐ๊ณผ 1 โ€” 17์ฐจ(2024) ์†Œ๋“๋ถ„์œ„๋ณ„ ๋น„์ค‘: ์—ญU์žยถ

Inย [3]:
r=res[res.wave==17].iloc[0]
pd.DataFrame({"๋ถ„์œ„":[f"D{d:02d}" for d in range(1,11)],
             "์ฃผ๋ฅ˜/์†Œ๋น„(%)":[r[f"D{d:02d}_alc_con_pct"] for d in range(1,11)]})
Out[3]:
๋ถ„์œ„ ์ฃผ๋ฅ˜/์†Œ๋น„(%)
0 D01 0.247
1 D02 0.474
2 D03 0.652
3 D04 0.747
4 D05 0.770
5 D06 0.692
6 D07 0.901
7 D08 0.897
8 D09 0.787
9 D10 0.745

D01(์ตœ์ €) 0.25% โ†’ D07 0.90%(์ •์ ) โ†’ D10(์ตœ๊ณ ) 0.75% โ€” ์ค‘์‚ฐ์ธต ์ตœ๋‹ค๋ถ€๋‹ดยท์ตœ๊ณ ์†Œ๋“ ์ƒ๋‹จ ์—ญ์ง„. ์ ˆ๋Œ€์•ก์€ ์†Œ๋“๋”ฐ๋ผ ์ฆ๊ฐ€ํ•˜๋‚˜ ๋น„์ค‘์€ ์—ญU์ž.

๊ฒฐ๊ณผ 2 โ€” ๊ตฌ์กฐ์  ๊ฐ์†Œ(17๋…„ ๋ฐ˜๊ฐ)ยถ

Inย [4]:
res[["survey_year","alc_share_con_pct_all","purchase_rate_pct"]]
Out[4]:
survey_year alc_share_con_pct_all purchase_rate_pct
0 2008 1.536 49.9
1 2009 1.093 46.7
2 2010 1.083 45.5
3 2011 0.989 42.4
4 2012 1.024 41.0
5 2013 0.806 37.1
6 2014 0.917 38.4
7 2015 0.841 37.4
8 2016 0.755 36.6
9 2017 0.817 38.2
10 2018 0.892 39.5
11 2019 0.898 41.1
12 2020 0.959 42.4
13 2021 0.863 38.4
14 2022 0.877 38.9
15 2023 0.879 38.6
16 2024 0.754 37.4

๊ฐ€์ •์šฉ ์ฃผ๋ฅ˜/์†Œ๋น„ ๋น„์ค‘ 2008๋…„ 1.54% โ†’ 2024๋…„ 0.75%๋กœ ๋ฐ˜๊ฐ, ๊ตฌ์ž…๊ฐ€๊ตฌ์œจ 50%โ†’37%. ๊ตฌ์กฐ์  ์ˆ˜์š” ๊ฐ์†Œ๋ฅผ ๊ฐ€๊ตฌํŒจ๋„๋กœ ํ™•์ธ.