# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] id="cltNUzHKzBht"
# #Análisis y Visualización de datos
# # Entregable #1
# # ¿Cuáles son los lenguajes de programación asociados a los mejores salarios?

# + [markdown] id="I7-ccKxf4mH4"
# ## Lectura del Dataset

# + id="TnSjxYoW4HZQ"
import io
import matplotlib
import matplotlib.pyplot as plt
import numpy
import pandas as pd
import seaborn
import re
import requests


# + id="dzFy3KSescSB"
seaborn.set_context('talk')
url = 'https://cs.famaf.unc.edu.ar/~mteruel/datasets/diplodatos/sysarmy_survey_2020_processed.csv'
dataset_metadata = {
  'year': 2019,
  'part': 2,
  'skiprows': 0,
  'publish_date': '2019-08-15',
  'minimum_salary': 12500, # https://es.wikipedia.org/wiki/Anexo:Salario_m%C3%ADnimo_en_Argentina
}
df = pd.read_csv(url)
raw_dataframe = None
source = requests.get(url.format(dataset_metadata['year'], dataset_metadata['part'])).content
raw_dataframe = pd.read_csv(io.StringIO(source.decode('utf-8')), skiprows=dataset_metadata['skiprows'], thousands='.', decimal=',')
# -

pd.set_option('display.max_columns', None)
df.head(2)

# + colab={"base_uri": "https://localhost:8080/"} id="S3QwgVps9Ryu" outputId="5deee474-d86e-4f8b-d6c9-f9d9719c1760"
df['salary_monthly_NETO'].describe().apply(lambda s: '{0:.2f}'.format(s))

# + colab={"base_uri": "https://localhost:8080/"} id="Em5QFIhH9fML" outputId="e2b88045-dc1e-4df9-ffd9-35e178dd7d60"
raw_dataframe['salary_monthly_NETO'].describe().apply(lambda s: '{0:.2f}'.format(s))

# + [markdown] id="ZDKEvGntAFST"
# Trabajo más sobre el raw_dataframe, como eleiminando los valores muy altos. Pero la media y std dan muy feos. 

# + colab={"base_uri": "https://localhost:8080/"} id="seDAkObHAMYF" outputId="66f4891c-eb9e-4481-8079-c97ba9c1c554"
raw_dataframe=raw_dataframe[raw_dataframe['salary_monthly_NETO']<3000000]
raw_dataframe['salary_monthly_NETO'].describe().apply(lambda s: '{0:.2f}'.format(s))

# + colab={"base_uri": "https://localhost:8080/", "height": 291} id="Jtum5bfx5D0E" outputId="c505fb32-e099-4a5d-93a3-f16d4e4e94bb"
df[:3]

# + colab={"base_uri": "https://localhost:8080/"} id="eifVtAfV3z5Q" outputId="a12631de-9561-428d-b886-edc6e72fd1ee"
df['work_role']=='Developer'

# + [markdown] id="matz4NH2xTdi"
# ## Selección de columnas relevantes para analizar

# + id="GC6rgTToxbDw"
relevant_columns = ['tools_programming_languages', 'salary_monthly_NETO', 'work_role']


# + [markdown] id="pZ4LGZOHrOhy"
# ## Preparación de datos: todo lo necesario para facilitar la manipulación de datos y estudio de variables.

# + colab={"base_uri": "https://localhost:8080/", "height": 204} id="XZ3rMyPAsxyn" outputId="6a45152c-db37-45f3-b519-5aa7e608e506"
# Convert the comma-separated string of languages to a list of string.
# Remove 'ninguno de los anteriores' option, spaces and training commas.
def split_languages(languages_str):
  if not isinstance(languages_str, str):
    return []
  # Remove 'other' option
  languages_str = languages_str.lower()\
    .replace('ninguno de los anteriores', '')
  # Split string into list of items
  # Remove spaces and commas for each item
  return [lang.strip().replace(',', '')
          for lang in languages_str.split()]

# Create a new column with the list of languages
df.loc[:, 'cured_programming_languages'] = df.tools_programming_languages\
    .apply(split_languages)
if 'cured_programming_languages' not in relevant_columns:
    relevant_columns.append('cured_programming_languages') 

# Duplicate each row of df for each programming language
# mentioned in the response.
# We only include in df_lang the columns we are going to analyze later, so we
# don't duplicate innecesary information.
df_lang = df.cured_programming_languages\
    .apply(pd.Series).stack()\
    .reset_index(level=-1, drop=True).to_frame()\
    .join(df[relevant_columns])\
    .rename(columns={0: 'programming_language'})
# Horrible programming style! But a lot of data science code can be written with
# as concatenations of functions (pipelines), and there's no elegant way of
# doing that on Python.
df_lang[:5]

# + [markdown] id="4FHSwCR0yJKm"
# ## Seleccionar las filas relevantes para analizar. 
# Esto incluye la eliminación de valores extremos y erróneos, pero también puede enfocar el análisis en una sub-población. Por ejemplo, se pueden limitar a personas con un salario mayor que 10000 pesos, o a las personas que trabajan sólo en "Data Science", pero deben justificar su elección y reformular la pregunta inicial de ser necesario.
# * Obtener una lista de los lenguajes de programación más populares. Decidir cuántos y cuáles seleccionan para incluir en el análisis.
# * Para cada una de las otras columnas del punto anterior, elegir los rangos o valores seleccionan para incluir en el análisis.

# + [markdown] id="tGCyX_d_yg0m"
# ### Análisis de sub-población
#
# * Seleccionaría de la columna word_role solo desarrolladores ya que consideramos que es la subpobablación cuyo salarío tiene relación directa con su expertise en programación.
#
#

# + jupyter={"outputs_hidden": true}
df_lang['work_role'].unique() ##Buscaria todo lo que diga developer y desarrollador
# -

df_lang['work_role_clean'] = df_lang['work_role'].apply(lambda x: str.lower(x))

df_developer_fin =df_lang[df_lang['work_role_clean'].str.contains("developer|desarrollador")]

df_developer_fin.count()

df_developer_fin.head(3)

df_developer_fin['work_role_clean'].unique()

df_developer_fin['work_role_clean'].value_counts()

# + colab={"base_uri": "https://localhost:8080/", "height": 359} id="aAsvdyG46Ktc" outputId="5f008ead-b4e6-420c-d514-3f18c1bd2a18"
df_lang_work=df_developer_fin
language_count = df_lang_work.programming_language.value_counts()\
    .reset_index()\
    .rename(columns={'index': 'language', 'programming_language': 'frequency'})
most_important_lang=language_count[:10]
most_important_lang

# + [markdown] id="H6cGBk6HSZgs"
# `***<NAME>***`
#
# Buscamos que los valores de los datos sean similares. Filtramos y quitamos salarios menores de 10:

# + colab={"base_uri": "https://localhost:8080/"} id="aoTXwG2EQ9ul" outputId="5327017a-ba15-449a-9f63-1af82d2f55b7"
df_lang_work.count()

# + colab={"base_uri": "https://localhost:8080/", "height": 419} id="MsP-JDcBRlvM" outputId="3e4c0a62-bbe8-4d24-ddbd-9efb56cc7390"
zeros_salary_monthly_NETO = df_lang_work[df_lang_work["salary_monthly_NETO"]>10]
malos = df_lang_work[df_lang_work["salary_monthly_NETO"]<10]
zeros_salary_monthly_NETO

# + colab={"base_uri": "https://localhost:8080/"} id="mmLhmg0xSPpN" outputId="9b7a31a3-01df-41cd-c6e1-515288f5e87d"
malos.count()

# + colab={"base_uri": "https://localhost:8080/"} id="N1Fs5A2FR64K" outputId="0c8c3e14-6a07-4d26-a00e-910192101478"
zeros_salary_monthly_NETO.count()

# + id="FzWMnLPR3mM7"
df_martin_r=zeros_salary_monthly_NETO.copy()

# + [markdown] id="xJtZ3R-iCO62"
# ## Selección de métricas
# Comparar las distribuciones de salario para cada lenguaje utilizando visualizaciones. Como la visualización es el producto final, debe ser clara y mostrar información relevante.

# + [markdown] id="5xtVrb4jCeUz"
# Boxplot: Lenguage vs Salario
#
# Histograma: hay que llevar salario a un rango (bins)
#
# crosstab
#
# scaterplot: permite evaluar 3D. Podemos evaluar work_role vs language vs salario
#
# language vs salario vs frec (ocurrencia de encuestas)

# + colab={"base_uri": "https://localhost:8080/", "height": 407} id="oMtOEGYcQdwp" outputId="aa372e85-309b-4265-c13b-b8576369d7e3"
df_lang_work

# + colab={"base_uri": "https://localhost:8080/", "height": 197} id="Hs69LIRQhFcy" outputId="01e540f4-e012-4f21-b365-17030b09eb2b"
df_lang_work2 = df_lang_work
cantidad = df_lang_work2["programming_language"].value_counts()
cantidad = pd.DataFrame(data=cantidad)
cantidad.head()

# + colab={"base_uri": "https://localhost:8080/", "height": 552} id="NuRh_ynUUC7V" outputId="fd59e780-f765-48c0-bf02-dd341f8c1af9"
lenguajes = cantidad["denominacion"].head(15)

# + id="0vGTaPMbmOnw"
cantidad["sal_acum"] = df_lang_work2.groupby(["programming_language"])["salary_monthly_NETO"].sum()
cantidad.head()

# + id="ur9V6VbCnjSe"
cantidad["mean"]=cantidad["sal_acum"]/cantidad["programming_language"]

# + id="nmMTrJ_qRm8S"
cantidad[""]= cantidad.index
cantidad.columns

# + id="c30rurMmSbfW"
cantidad["denominacion"]= cantidad.index

# + [markdown] id="G6mLjPITUt_v"
# #Comentario => <NAME>.
# Chicos... lo que hice aqui me costo un huevo. jaj, me falta mucha práctica. Que hice? es filtrar los 15 lenguajes más respondidos y calcularles el promedio de lo que ganan. 
#
# Luego, los que en promedio no declararon casi nada de ingreso y al final los que declararon un número enorme de ingresos. 
#
# Creo que esto es más curación de datos, pero entiendo que estaría bueno mencionarlo como al margen. Dejo el código bastante rupestre. Luego si quieren lo acomodamos de manera más elegante

# + id="DJYD14iEoIs4"
seaborn.catplot(x="denominacion", y="mean", data=cantidad, kind="bar", legend=True,height=5, aspect=4/1, order=lenguajes)

# + id="BL3w23lJdD5F"
cantidad2 = cantidad.sort_values(by="mean")

# + id="Br0DolGUVnx3"
lenguajes2 = cantidad2["denominacion"].head(15)
seaborn.catplot(x="denominacion", y="mean", data=cantidad2, kind="bar", legend=True,height=5, aspect=4/1, order=lenguajes2)

# + id="FW-BEc22WiOC"
cantidad2.head()

# + id="7DM5x3mpVpvq"


# + id="Li2aCX_gWC8v"
cantidad3.head(10)

# + id="Xi3RPY69V6IR"
lenguajes3 = cantidad3["denominacion"].head(15)
seaborn.catplot(x="denominacion", y="mean", data=cantidad3, kind="bar", legend=True,height=5, aspect=4/1, order=lenguajes3)

# + [markdown] id="buvc9CBT3RT0"
# #<NAME>

# + id="fXGB4B5Zx0an"
#inicialización de variable para Martin R.
df_martin_r=zeros_salary_monthly_NETO.copy()
salary_col='salary_monthly_NETO'

# + [markdown] id="RfCAbjhx2WoF"
# ##Tendencia central

# + colab={"base_uri": "https://localhost:8080/"} id="fHSWQ9Q32nR1" outputId="4131ecb6-e4f0-4d46-9596-6ac39f041a22"
#análisis incial de los datos
df_martin_r[salary_col].describe().apply(lambda s: '{0:.2f}'.format(s))

# + colab={"base_uri": "https://localhost:8080/"} id="1hLdRrhBxIyP" outputId="ce6f1dc2-2d00-4fed-8f13-d34840e018db"
df_martin_r[salary_col].mean(), df_martin_r[salary_col].median()

# + [markdown] id="dUkNPrBOySSA"
# Siendo que la media y mediana dan muy distintas, y además aún tenemos mínimos muy extraños (13?) evaluo esos extremos. Una media > mediana, indica un sesgo o asimetría hacia la derecha.

# + id="WUt3rOrwzYOx"
#que son lo valores pequeños que no tienen sentido para un salario?
df[df['salary_monthly_NETO']<1000]

# + [markdown] id="WVT3Tj3Q0aAC"
# Si analizamos los salarios menores que mil vamos a encontrar que se cargaron con un . indicando la unidad de 1000 y para python es una ','. Procedemos a arreglar esto.**PERO NO SE COMO SE HACE**

# + colab={"base_uri": "https://localhost:8080/"} id="AQjjE83g0zKf" outputId="6607a721-1a6c-4f3e-da60-8a7763ff1049"
df_salario_correccion_unidad = df[df['salary_monthly_NETO']<1000]
df_salario_correccion_unidad=df_salario_correccion_unidad['salary_monthly_NETO'].replace('.',' ',regex=False)
df_salario_correccion_unidad

# + [markdown] id="wj8dwX391yG5"
# ##Análisis usando Histrograma
#
# Me parece que hay que comenzar por analizar los sueldos de manera global, identificar outliers y ver como se distribuye. Ahí ir a los lenguajes y verificar si los valores son lógicos o es un lenguage influenciado por pocos datos quizás u otro tema. 

# + id="FCHIwHyf-ep6"
#histograma

# + [markdown] id="IcndY7L_3YQm"
# ##Análisis usando Boxplot

# + id="ikYOzAOv3Wpm"
df_martin_r[:3]

# + [markdown] id="QdjUQe1e6N2K"
# Elimación de valores extremos

# + colab={"base_uri": "https://localhost:8080/"} id="h-toOhya6Ric" outputId="ee88bb57-21cf-4431-ac2b-81ea226249da"
k = 90
percentile_90 = df[salary_col].quantile(k / 100)
n_below = len(df[df[salary_col] < percentile_90])
n_above = len(df[df[salary_col] > percentile_90])
print('Percentil {} de la columna {}: {}'.format(k, salary_col, percentile_90))
print('% de datos menor que percentil {}: {}'.format(k, n_below / len(df)))
print('% de datos mayor que percentil {}: {}'.format(k, n_above / len(df)))

# + colab={"base_uri": "https://localhost:8080/"} id="nAR_hMRd6yuI" outputId="e28a6705-5056-4b2d-8eb2-f8e3d884d1b0"
df[salary_col].quantile([.95, .98, .99, .995, .998])

# + colab={"base_uri": "https://localhost:8080/"} id="jwksLsY57y3T" outputId="c262109f-2eb0-4525-c55f-20c389e9add0"
df_martin_r_under_p90=df_martin_r[df_martin_r[salary_col]<percentile_90].copy()
df_martin_r_under_p90.count()

# + [markdown] id="TGzO_BvY8kwf"
# Seleccion de los lenguajes más relevantes

# + colab={"base_uri": "https://localhost:8080/", "height": 347} id="VOCfXn5d8o4-" outputId="20366b77-822f-420b-e4b6-008adf73da95"
#criterio 1: los que más datos tienen
language_count_aux = df_martin_r_under_p90.programming_language.value_counts()\
    .reset_index()\
    .rename(columns={'index': 'language', 'programming_language': 'frequency'})
most_important_lang=language_count_aux[:10]
most_important_lang

# + colab={"base_uri": "https://localhost:8080/"} id="jm3gzAEMALMD" outputId="ea9ec47a-17ac-4679-e280-75ed0697d3d7"
#Necesito una manera más alegante de transformar a una serie los most_important_lang
lenguajes_mas_representativos=['javascript','php','html','sql','css','java']
df_with_most_representat_language=df_martin_r_under_p90[df_martin_r_under_p90.programming_language.isin(lenguajes_mas_representativos)].copy()
df_with_most_representat_language.count()

# + colab={"base_uri": "https://localhost:8080/", "height": 410} id="rYteyqWU3_jj" outputId="587d671a-5ad6-4e4f-b7a4-ce4365e9b57d"
plt.figure(figsize=(12, 6))
seaborn.boxenplot(data=df_with_most_representat_language, x='salary_monthly_NETO', y='programming_language',color='orangered')
plt.ticklabel_format(style='plain', axis='x')

StarcoderdataJupyterScriptsDedupFiltered