mirror of
https://github.com/koodiklinikka/palkkakysely.git
synced 2026-01-26 03:14:03 +00:00
121 lines
3.5 KiB
Python
121 lines
3.5 KiB
Python
import re
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
|
|
COLUMN_MAP = {
|
|
"Missä kaupungissa työpaikkasi pääasiallinen toimisto sijaitsee?": "Kaupunki",
|
|
"Työaika (jos työsuhteessa)": "Työaika",
|
|
"Etänä vai paikallisesti?": "Etä",
|
|
"Vuositulot (sis. bonukset, osingot yms) / Vuosilaskutus (jos laskutat)": "Vuositulot",
|
|
"Kuukausipalkka (jos työntekijä) (brutto)": "Kuukausipalkka",
|
|
"Onko palkkasi nykyroolissasi mielestäsi kilpailukykyinen?": "Kilpailukykyinen",
|
|
}
|
|
|
|
ETATYO_MAP = {
|
|
"Pääosin tai kokonaan etätyö": "Etä",
|
|
"Pääosin tai kokonaan toimistolla": "Toimisto",
|
|
"Noin 50/50 hybridimalli": "50/50",
|
|
}
|
|
|
|
|
|
def map_sukupuoli(value: str):
|
|
if isinstance(value, str):
|
|
value = value.lower()
|
|
if "nainen" in value or "female" in value:
|
|
return "nainen"
|
|
|
|
if (
|
|
"mies" in value
|
|
or "uros" in value
|
|
or "miäs" in value
|
|
or "äiä" in value
|
|
or "male" in value
|
|
or value == "m"
|
|
):
|
|
return "mies"
|
|
return "muu" # Map the handful of outliers into "muu" (so a given value but not specified)
|
|
return value
|
|
|
|
|
|
def map_vuositulot(r):
|
|
if r["Vuositulot"] is np.nan:
|
|
return r["Kuukausipalkka"] * 12.5
|
|
return r["Vuositulot"]
|
|
|
|
|
|
def map_numberlike(d):
|
|
if isinstance(d, str):
|
|
try:
|
|
return float(re.sub("\s+", "", d))
|
|
except ValueError:
|
|
pass
|
|
return d
|
|
|
|
|
|
def map_ika(d):
|
|
if d == "30-35 v": # Early answers had a wrong bracket here
|
|
d = "31-35 v"
|
|
return d
|
|
|
|
|
|
def read_data() -> pd.DataFrame:
|
|
df: pd.DataFrame = pd.read_excel(
|
|
"data/results.xlsx",
|
|
skiprows=[1], # Google Sheets exports one empty row
|
|
)
|
|
df.rename(columns=COLUMN_MAP, inplace=True)
|
|
|
|
df["Kaupunki"].replace(
|
|
"PK-Seutu (Helsinki, Espoo, Vantaa)", "PK-Seutu", inplace=True
|
|
)
|
|
df["Kaupunki"] = df["Kaupunki"].astype("category")
|
|
df["Sukupuoli"] = df["Sukupuoli"].apply(map_sukupuoli).astype("category")
|
|
df["Ikä"] = df["Ikä"].apply(map_ika).astype("category")
|
|
# Turn työaika into 0% - 100%
|
|
df["Työaika"] = pd.to_numeric(df["Työaika"], errors="coerce").clip(0, 1)
|
|
|
|
df["Etä"] = df["Etä"].map(ETATYO_MAP).astype("category")
|
|
df["Kilpailukykyinen"].replace({"Kyllä": True, "Ei": False}, inplace=True)
|
|
|
|
# Try to clean up numbers with spaces, etc. to real numbers
|
|
df["Kuukausipalkka"] = df["Kuukausipalkka"].apply(map_numberlike)
|
|
df["Vuositulot"] = df["Vuositulot"].apply(map_numberlike)
|
|
|
|
# Fill in Vuositulot as 12.5 * Kk-tulot if empty
|
|
df["Vuositulot"] = df.apply(map_vuositulot, axis=1)
|
|
|
|
# Synthesize kk-tulot from Vuositulot
|
|
df["Kk-tulot"] = pd.to_numeric(df["Vuositulot"], errors="coerce") / 12
|
|
return df
|
|
|
|
|
|
def force_tulot_numeric(df):
|
|
df["Kuukausipalkka"] = pd.to_numeric(df["Kuukausipalkka"], errors="coerce")
|
|
df["Vuositulot"] = pd.to_numeric(df["Vuositulot"], errors="coerce")
|
|
return df
|
|
|
|
|
|
def force_age_numeric(df):
|
|
age_map = {}
|
|
for cat in df["Ikä"].cat.categories:
|
|
m = re.match("^(\d+)-(\d+) v", cat)
|
|
if m:
|
|
age_map[cat] = int(round(float(m.group(1)) + float(m.group(2))) / 2)
|
|
df["Ikä"] = df["Ikä"].apply(lambda r: age_map.get(r, r))
|
|
return df
|
|
|
|
|
|
def main():
|
|
pd.set_option("display.max_column", None)
|
|
pd.set_option("display.max_rows", None)
|
|
pd.set_option("display.max_seq_items", None)
|
|
pd.set_option("display.max_colwidth", 500)
|
|
pd.set_option("expand_frame_repr", True)
|
|
df = read_data()
|
|
print(df.head())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|