Close Menu
    Facebook LinkedIn YouTube WhatsApp X (Twitter) Pinterest
    Trending
    • June deadline approaches for Hawthorne sale process
    • Today’s NYT Mini Crossword Answers for June 4
    • New tiny nudibranch species discovered in Taiwan
    • Why the Budget’s CGT changes are a disaster for angel investors and startups
    • OpenAI and Anthropic Sign Letter to Prevent AI-Developed Biological Weapons
    • New York sports betting statements bill advances
    • SwitchBot Launches the Most Complete Home Weather Station I’ve Seen
    • What It Takes for Future-Ready Power Distribution
    Facebook LinkedIn WhatsApp
    Times FeaturedTimes Featured
    Thursday, June 4
    • Home
    • Founders
    • Startups
    • Technology
    • Profiles
    • Entrepreneurs
    • Leaders
    • Students
    • VC Funds
    • More
      • AI
      • Robotics
      • Industries
      • Global
    Times FeaturedTimes Featured
    Home»Artificial Intelligence»Exploratory Data Analysis for Credit Scoring with Python
    Artificial Intelligence

    Exploratory Data Analysis for Credit Scoring with Python

    Editor Times FeaturedBy Editor Times FeaturedMarch 12, 2026No Comments18 Mins Read
    Facebook Twitter Pinterest Telegram LinkedIn Tumblr WhatsApp Email
    Share
    Facebook Twitter LinkedIn Pinterest Telegram Email WhatsApp Copy Link


    challenge, it’s typically tempting to leap to modeling. But step one and a very powerful one is to grasp the information.

    In our earlier post, we offered how the databases used to construct credit score scoring fashions are constructed. We additionally spotlight the significance of asking proper questions:

    • Who’re the purchasers?
    • What sorts of loans are they granted?
    • What traits seem to clarify default threat?

    On this article, we illustrate this foundational step utilizing an open-source dataset accessible on Kaggle: the Credit score Scoring Dataset. This dataset comprises 32,581 observations and 12 variables describing loans issued by a financial institution to particular person debtors.

    These loans cowl a variety of financing wants — medical, private, academic, {and professional} — in addition to debt consolidation operations. Mortgage quantities vary from $500 to $35,000.

    The variables seize two dimensions:

    • contract traits (mortgage quantity, rate of interest, objective of financing, credit score grade, and time elapsed since mortgage origination),
    • borrower traits (age, earnings, years {of professional} expertise, and housing standing).

    The mannequin’s goal variable is default, which takes the worth 1 if the shopper is in default and 0 in any other case.

    Right now, many instruments and an rising variety of AI brokers are able to mechanically producing statistical descriptions of datasets. Nonetheless, performing this evaluation manually stays a superb train for newcomers. It builds a deeper understanding of the information construction, helps spotlight potential anomalies, and helps the identification of variables which may be predictive of threat.

    On this article, we take a easy tutorial method to statistically describing every variable within the dataset.

    • For categorical variables, we analyze the variety of observations and the default fee for every class.
    • For steady variables, we discretize them into 4 intervals outlined by the quartiles:
      • ]min; Q1], ]Q1; Q2], ]Q2; Q3] and ]Q3; max]

    We then apply the identical descriptive evaluation to those intervals as for categorical variables. This segmentation is unfair and might be changed by different discretization strategies. The aim is just to get an preliminary learn on how threat behaves throughout the totally different mortgage and borrower traits.

    Descriptive Statistics of the Modeling Dataset

    Distribution of the Goal Variable (loan_status)

    This variable signifies whether or not the mortgage granted to a counterparty has resulted in a reimbursement default. It takes two values: 0 if the shopper isn’t in default, and 1 if the shopper is in default.

    Over 78% of consumers haven’t defaulted. The dataset is imbalanced, and it is very important account for this imbalance throughout modeling.

    The following related variable to research could be a temporal one. It could enable us to review how the default fee evolves over time, confirm its stationarity, and assess its stability and its predictability.

    Sadly, the dataset comprises no temporal info. We have no idea when every remark was recorded, which makes it unattainable to find out whether or not the loans have been issued throughout a interval of financial stability or throughout a downturn.

    This info is nonetheless important in credit score threat modeling. Borrower habits can differ considerably relying on the macroeconomic surroundings. As an illustration, throughout monetary crises — such because the 2008 subprime disaster or the COVID-19 pandemic — default charges sometimes rise sharply in comparison with extra favorable financial intervals.

    The absence of a temporal dimension on this dataset due to this fact limits the scope of our evaluation. Particularly, it prevents us from learning how threat dynamics evolve over time and from evaluating the potential robustness of a mannequin in opposition to financial cycles.

    We do, nevertheless, have entry to the variable cb_person_cred_hist_length, which represents the size of a buyer’s credit score historical past, expressed in years.

    Distribution by Credit score Historical past Size (cb_person_cred_hist_length)

    This variable has 29 distinct values, starting from 2 to 30 years. We’ll deal with it as a steady variable and discretize it utilizing quantiles.

    A number of observations might be drawn from the desk above. First, greater than 56% of debtors have a credit score historical past of 4 years or much less, indicating that a big proportion of shoppers within the dataset have comparatively brief credit score histories.

    Second, the default fee seems pretty steady throughout intervals, hovering round 21%. That stated, debtors with shorter credit score histories are likely to exhibit barely riskier habits than these with longer ones, as mirrored of their larger default charges.

    Distribution by Earlier Default (cb_person_default_on_file)

    This variable signifies whether or not the borrower has beforehand defaulted on a mortgage. It due to this fact gives beneficial details about the previous credit score habits of the shopper.

    It has two doable values:

    • Y: the borrower has defaulted previously
    • N: the borrower has by no means defaulted

    On this dataset, greater than 80% of debtors don’t have any historical past of default, suggesting that almost all of shoppers have maintained a passable reimbursement document.

    Nevertheless, a transparent distinction in threat emerges between the 2 teams. Debtors with a earlier default historical past are considerably riskier, with a default fee of about 38%, in contrast with round 18% for debtors who’ve by no means defaulted.

    This result’s in line with what is usually noticed in credit score threat modeling: previous reimbursement habits is usually one of many strongest predictors of future default.

    Distribution by Age

    The presence of the age variable on this dataset signifies that the loans are granted to particular person debtors (retail shoppers) fairly than company entities. To higher analyze this variable, we group debtors into age intervals based mostly on quartiles.

    The dataset contains debtors throughout a variety of ages. Nevertheless, the distribution is strongly skewed towards youthful people: greater than 70% of debtors are beneath 30 years outdated.

    The evaluation of default charges throughout the age teams reveals that the highest threat is concentrated within the first quartile, adopted by the second quartile. In different phrases, youthful debtors look like the riskiest phase on this dataset.

    Distribution by Annual Revenue

    Debtors’ annual earnings on this dataset ranges from $4,000 to $6,000,000. To investigate its relationship with default threat, we divide earnings into 4 intervals based mostly on quartiles.

    The outcomes present that the best default charges are concentrated amongst debtors with the bottom incomes, significantly within the first quartile ($4,000–$385,00) and the second quartile ($385,00–$55,000).

    As earnings will increase, the default fee regularly decreases. Debtors within the third quartile ($55,000–$792,000) and the fourth quartile ($792,000–$600,000) exhibit noticeably decrease default charges.

    Total, this sample suggests an inverse relationship between annual earnings and default threat, which is in line with customary credit score threat expectations: debtors with larger incomes sometimes have larger reimbursement capability and monetary stability, making them much less prone to default.

    Distribution by Residence Possession

    This variable describes the borrower’s housing standing. The classes embody RENT (tenant), MORTGAGE (house owner with a mortgage), OWN (house owner with no mortgage), and OTHER (different housing preparations).

    On this dataset, roughly 50% of debtors are renters, 40% are owners with a mortgage, 8% personal their house outright, and about 2% fall into the “OTHER” class.

    The evaluation reveals that the best default charges are noticed amongst renters (RENT) and debtors labeled as “OTHER.” In distinction, owners with no mortgage (OWN) exhibit the bottom default charges, adopted by debtors with a mortgage (MORTGAGE).

    Distributionby particular person employment size person_emp_length

    This variable measures the borrower’s employment size in years. To investigate its relationship with default threat, debtors are grouped into 4 intervals based mostly on quartiles: the first quartile (0–2 years), the second quartile (2–4 years), the third quartile (4–7 years), and the fourth quartile (7 years or extra).

    The evaluation exhibits that the best default charges are concentrated amongst debtors with the shortest employment histories, significantly these within the first quartile (0–2 years) and the second quartile (2–4 years).

    As employment size will increase, the default fee tends to say no. Debtors within the third quartile (4–7 years) and the fourth quartile (7 years or extra) exhibit decrease default charges.

    Total, this sample suggests an inverse relationship between employment size and default threat, indicating that debtors with longer employment histories could profit from larger earnings stability and monetary safety, which reduces their chance of default.

    Distribution by mortgage intent

    This categorical variable describes the objective of the mortgage requested by the borrower. The classes embody EDUCATION, MEDICAL, VENTURE (entrepreneurship), PERSONAL, DEBTCONSOLIDATION, and HOMEIMPROVEMENT.

    The variety of debtors is pretty balanced throughout the totally different mortgage functions, with a barely larger share of loans used for training (EDUCATION) and medical bills (MEDICAL).

    Nevertheless, the evaluation reveals notable variations in threat throughout classes. Debtors in search of loans for debt consolidation (DEBTCONSOLIDATION) and medical functions (MEDICAL) exhibit larger default charges. In distinction, loans supposed for training (EDUCATION) and entrepreneurial actions (VENTURE) are related to decrease default charges.

    Total, these outcomes recommend that the objective of the mortgage could also be an necessary threat indicator, as totally different financing wants can mirror various ranges of economic stability and reimbursement capability.

    Distribution by mortgage grade

    This categorical variable represents the mortgage grade assigned to every borrower, sometimes based mostly on an evaluation of their credit score threat profile. The grades vary from A to G, the place A corresponds to the lowest-risk loans and G to the highest-risk loans.

    On this dataset, greater than 80% of debtors are assigned grades A, B, or C, indicating that almost all of loans are thought of comparatively low threat. In distinction, grades D, E, F, and G correspond to debtors with larger credit score threat, and these classes account for a a lot smaller share of the observations.

    The distribution of default charges throughout the grades exhibits a transparent sample: the default fee will increase because the mortgage grade deteriorates. In different phrases, debtors with decrease credit score grades are likely to exhibit larger chances of default.

    This result’s in line with the aim of the grading system itself, as mortgage grades are designed to summarize the borrower’s creditworthiness and related threat stage.

    Distribution by Mortgage Quantity

    This variable represents the mortgage quantity requested by the borrower. On this dataset, mortgage quantities vary from $500 to $35,000, which corresponds to comparatively small shopper loans.

    The evaluation of default charges throughout the quartiles exhibits that the best threat is concentrated amongst debtors within the higher vary of mortgage quantities, significantly within the fourth quartile ($20,000–$35,000), the place default charges are larger.

    Distribution by mortgage rate of interest (loan_int_rate)

    This variable represents the rate of interest utilized to the mortgage granted to the borrower. On this dataset, rates of interest vary from 5% to 24%.

    To investigate the connection between rates of interest and default threat, we group the observations into quartiles. The outcomes present that the best default charges are concentrated within the higher vary of rates of interest, significantly within the fourth quartile (roughly 13%–24%).

    Distribution by mortgage p.c earnings

    This variable measures the share of a borrower’s annual earnings allotted to mortgage reimbursement. It signifies the monetary burdenassociated with the mortgage relative to the borrower’s earnings.

    The evaluation exhibits that the best default charges are concentrated within the higher quartile, the place debtors allocate between 20% and 100% of their earnings to mortgage reimbursement.

    Conclusion

    On this evaluation, we’ve got described every of the 12 variables within the dataset. This exploratory step allowed us to construct a transparent understanding of the information and shortly summarize its key traits within the introduction.

    Up to now, one of these evaluation was typically time-consuming and sometimes required the collaboration of a number of knowledge scientists to carry out the statistical exploration and produce the ultimate reporting. Whereas the interpretations of various variables could generally seem repetitive, such detailed documentation is usually required in regulated environments, significantly in fields like credit score threat modeling.

    Right now, nevertheless, the rise of synthetic intelligence is reworking this workflow. Duties that beforehand required a number of days of labor can now be accomplished in lower than half-hour, beneath the supervision of a statistician or knowledge scientist. On this setting, the professional’s position shifts from manually performing the evaluation to guiding the method, validating the outcomes, and guaranteeing their reliability.

    In observe, it’s doable to design two specialised AI brokers at this stage of the workflow. The primary agent assists with knowledge preparation and dataset building, whereas the second performs the exploratory evaluation and generates the descriptive reporting offered on this article.

    A number of years in the past, it was already really useful to automate these duties every time doable. On this publish, the tables used all through the evaluation have been generated mechanically utilizing the Python capabilities offered on the finish of this text.

    Within the subsequent article, we are going to take the evaluation a step additional by exploring variable remedy, detecting and dealing with outliers, analyzing relationships between variables, and performing an preliminary function choice.

    Picture Credit

    All photographs and visualizations on this article have been created by the creator utilizing Python (pandas, matplotlib, seaborn, and plotly) and excel, except in any other case acknowledged.

    References

    [1] Lorenzo Beretta and Alessandro Santaniello.
    Nearest Neighbor Imputation Algorithms: A Vital Analysis.
    Nationwide Library of Medication, 2016.

    [2] Nexialog Consulting.
    Traitement des données manquantes dans le milieu bancaire.
    Working paper, 2022.

    [3] John T. Hancock and Taghi M. Khoshgoftaar.
    Survey on Categorical Information for Neural Networks.
    Journal of Huge Information, 7(28), 2020.

    [4] Melissa J. Azur, Elizabeth A. Stuart, Constantine Frangakis, and Philip J. Leaf.
    A number of Imputation by Chained Equations: What Is It and How Does It Work?
    Worldwide Journal of Strategies in Psychiatric Analysis, 2011.

    [5] Majid Sarmad.
    Strong Information Evaluation for Factorial Experimental Designs: Improved Strategies and Software program.
    Division of Mathematical Sciences, College of Durham, England, 2006.

    [6] Daniel J. Stekhoven and Peter Bühlmann.
    MissForest—Non-Parametric Lacking Worth Imputation for Blended-Sort Information.Bioinformatics, 2011.

    [7] Supriyanto Wibisono, Anwar, and Amin.
    Multivariate Climate Anomaly Detection Utilizing the DBSCAN Clustering Algorithm.
    Journal of Physics: Convention Sequence, 2021.

    Information & Licensing

    The dataset used on this article is licensed beneath the Inventive Commons Attribution 4.0 Worldwide (CC BY 4.0) license.

    This license permits anybody to share and adapt the dataset for any objective, together with business use, supplied that correct attribution is given to the supply.

    For extra particulars, see the official license textual content: CC0: Public Domain.

    Disclaimer

    Any remaining errors or inaccuracies are the creator’s duty. Suggestions and corrections are welcome.

    Codes

    import pandas as pd
    from typing import Non-compulsory, Union
    
    
    def build_default_summary(
        df: pd.DataFrame,
        category_col: str,
        default_col: str,
        category_label: Non-compulsory[str] = None,
        include_na: bool = False,
        sort_by: str = "rely",
        ascending: bool = False,
    ) -> pd.DataFrame:
        """
        Construit un tableau de synthèse pour une variable catégorielle.
    
        Paramètres
        ----------
        df : pd.DataFrame
            DataFrame supply.
        category_col : str
            Nom de la variable catégorielle.
        default_col : str
            Colonne binaire indiquant le défaut (0/1 ou booléen).
        category_label : str, optionnel
            Libellé à afficher pour la première colonne.
            Par défaut : category_col.
        include_na : bool, default=False
            Si True, preserve les valeurs manquantes comme catégorie.
        sort_by : str, default="rely"
            Colonne de tri logique parmi {"rely", "defaults", "prop", "default_rate", "class"}.
        ascending : bool, default=False
            Sens du tri.
    
        Retour
        ------
        pd.DataFrame
            Tableau prêt à exporter.
        """
    
        if category_col not in df.columns:
            elevate KeyError(f"La colonne catégorielle '{category_col}' est introuvable.")
        if default_col not in df.columns:
            elevate KeyError(f"La colonne défaut '{default_col}' est introuvable.")
    
        knowledge = df[[category_col, default_col]].copy()
    
        # Validation minimale sur la cible
        # On convertit bool -> int ; sinon on suppose 0/1 documenté
        if pd.api.sorts.is_bool_dtype(knowledge[default_col]):
            knowledge[default_col] = knowledge[default_col].astype(int)
    
        # Gestion des NA de la variable catégorielle
        if include_na:
            knowledge[category_col] = knowledge[category_col].astype("object").fillna("Lacking")
        else:
            knowledge = knowledge[data[category_col].notna()].copy()
    
        grouped = (
            knowledge.groupby(category_col, dropna=False)[default_col]
            .agg(rely="dimension", defaults="sum")
            .reset_index()
        )
    
        total_obs = grouped["count"].sum()
        total_def = grouped["defaults"].sum()
    
        grouped["prop"] = grouped["count"] / total_obs if total_obs > 0 else 0.0
        grouped["default_rate"] = grouped["defaults"] / grouped["count"]
    
        sort_mapping = {
            "rely": "rely",
            "defaults": "defaults",
            "prop": "prop",
            "default_rate": "default_rate",
            "class": category_col,
        }
        if sort_by not in sort_mapping:
            elevate ValueError(
                "sort_by doit être parmi {'rely', 'defaults', 'prop', 'default_rate', 'class'}."
            )
    
        grouped = grouped.sort_values(sort_mapping[sort_by], ascending=ascending).reset_index(drop=True)
    
        total_row = pd.DataFrame(
            {
                category_col: ["Total"],
                "rely": [total_obs],
                "defaults": [total_def],
                "prop": [1.0 if total_obs > 0 else 0.0],
                "default_rate": [total_def / total_obs if total_obs > 0 else 0.0],
            }
        )
    
        abstract = pd.concat([grouped, total_row], ignore_index=True)
    
        
    
        abstract = abstract.rename(
            columns={
                category_col: category_label or category_col,
                "rely": "Nb of obs",
                "defaults": "Nb def",
                "prop": "Prop",
                "default_rate": "Default fee",
            }
        )
        abstract = abstract[[category_label or category_col, "Nb of obs", "Prop", "Nb def", "Default rate"]]
        return abstract
    
    
    def export_summary_to_excel(
        abstract: pd.DataFrame,
        output_path: str,
        sheet_name: str = "Abstract",
        title: str = "All perimeters",
    ) -> None:
        """
        Exporte le tableau de synthèse dans un fichier Excel avec mise en forme.
        Nécessite le moteur xlsxwriter.
        """
    
        with pd.ExcelWriter(output_path, engine="xlsxwriter") as author:
            #
    
            workbook = author.e book
            worksheet = workbook.add_worksheet(sheet_name)
    
            nrows, ncols = abstract.form
            total_excel_row = 2 + nrows  # +1 implicite Excel automotive index 0-based côté xlsxwriter pour set_row
            # Détail :
            # ligne 0 : titre fusionné
            # ligne 2 : header
            # données commencent ligne 3 (Excel visuel), mais xlsxwriter manipule en base 0
    
            # -------- Codecs --------
            border_color = "#4F4F4F"
            header_bg = "#D9EAF7"
            title_bg = "#CFE2F3"
            total_bg = "#D9D9D9"
            white_bg = "#FFFFFF"
    
            title_fmt = workbook.add_format({
                "daring": True,
                "align": "middle",
                "valign": "vcenter",
                "font_size": 14,
                "border": 1,
                "bg_color": title_bg,
            })
    
            header_fmt = workbook.add_format({
                "daring": True,
                "align": "middle",
                "valign": "vcenter",
                "border": 1,
                "bg_color": header_bg,
            })
    
            text_fmt = workbook.add_format({
                "border": 1,
                "align": "left",
                "valign": "vcenter",
                "bg_color": white_bg,
            })
    
            int_fmt = workbook.add_format({
                "border": 1,
                "align": "middle",
                "valign": "vcenter",
                "num_format": "# ##0",
                "bg_color": white_bg,
            })
    
            pct_fmt = workbook.add_format({
                "border": 1,
                "align": "middle",
                "valign": "vcenter",
                "num_format": "0.00%",
                "bg_color": white_bg,
            })
    
            total_text_fmt = workbook.add_format({
                "daring": True,
                "border": 1,
                "align": "middle",
                "valign": "vcenter",
                "bg_color": total_bg,
            })
    
            total_int_fmt = workbook.add_format({
                "daring": True,
                "border": 1,
                "align": "middle",
                "valign": "vcenter",
                "num_format": "# ##0",
                "bg_color": total_bg,
            })
    
            total_pct_fmt = workbook.add_format({
                "daring": True,
                "border": 1,
                "align": "middle",
                "valign": "vcenter",
                "num_format": "0.00%",
                "bg_color": total_bg,
            })
    
            # -------- Titre fusionné --------
            worksheet.merge_range(0, 0, 0, ncols - 1, title, title_fmt)
    
            # -------- Header --------
            worksheet.set_row(2, 28)
            for col_idx, col_name in enumerate(abstract.columns):
                worksheet.write(1, col_idx, col_name, header_fmt)
    
            # -------- Largeurs de colonnes --------
            column_widths = {
                0: 24,  # catégorie
                1: 14,  # Nb of obs
                2: 12,  # Nb def
                3: 10,  # Prop
                4: 14,  # Default fee
            }
            for col_idx in vary(ncols):
                worksheet.set_column(col_idx, col_idx, column_widths.get(col_idx, 15))
    
            # -------- Mise en forme cellule par cellule --------
            last_row_idx = nrows - 1
    
            for row_idx in vary(nrows):
                excel_row = 2 + row_idx  # données à partir de la ligne 3 (0-based xlsxwriter)
    
                is_total = row_idx == last_row_idx
    
                for col_idx, col_name in enumerate(abstract.columns):
                    worth = abstract.iloc[row_idx, col_idx]
    
                    if col_idx == 0:
                        fmt = total_text_fmt if is_total else text_fmt
                    elif col_name in ["Nb of obs", "Nb def"]:
                        fmt = total_int_fmt if is_total else int_fmt
                    elif col_name in ["Prop", "Default rate"]:
                        fmt = total_pct_fmt if is_total else pct_fmt
                    else:
                        fmt = total_text_fmt if is_total else text_fmt
    
                    worksheet.write(excel_row, col_idx, worth, fmt)
    
            # Optionnel : figer le header
            #worksheet.freeze_panes(3, 1)
    
            worksheet.set_default_row(24)
    
    
    def generate_categorical_report_excel(
        df: pd.DataFrame,
        category_col: str,
        default_col: str,
        output_path: str,
        sheet_name: str = "Abstract",
        title: str = "All perimeters",
        category_label: Non-compulsory[str] = None,
        include_na: bool = False,
        sort_by: str = "rely",
        ascending: bool = False,
    ) -> pd.DataFrame:
        """
        
        1. calcule le tableau
        2. l'exporte vers Excel
        3. renvoie aussi le DataFrame récapitulatif
        """
        abstract = build_default_summary(
            df=df,
            category_col=category_col,
            default_col=default_col,
            category_label=category_label,
            include_na=include_na,
            sort_by=sort_by,
            ascending=ascending,
        )
    
        export_summary_to_excel(
            abstract=abstract,
            output_path=output_path,
            sheet_name=sheet_name,
            title=title,
        )
    
        return abstract
    
    def discretize_variable_by_quartiles(
        df: pd.DataFrame,
        variable: str,
        new_var: str | None = None
    ) -> pd.DataFrame:
        """
        Discretize a steady variable into 4 intervals based mostly on its quartiles.
    
        The perform computes Q1, Q2 (median), and Q3 of the chosen variable and
        creates 4 bins comparable to the next intervals:
    
            ]min ; Q1], ]Q1 ; Q2], ]Q2 ; Q3], ]Q3 ; max]
    
        Parameters
        ----------
        df : pd.DataFrame
            Enter dataframe containing the variable to discretize.
    
        variable : str
            Title of the continual variable to be discretized.
    
        new_var : str, non-obligatory
            Title of the brand new categorical variable created. If None,
            the title "_quartile" is used.
    
        Returns
        -------
        pd.DataFrame
            A replica of the dataframe with the brand new quartile-based categorical variable.
        """
    
        # Create a duplicate of the dataframe to keep away from modifying the unique dataset
        knowledge = df.copy()
    
        # If no title is supplied for the brand new variable, create one mechanically
        if new_var is None:
            new_var = f"{variable}_quartile"
    
        # Compute the quartiles of the variable
        q1, q2, q3 = knowledge[variable].quantile([0.25, 0.50, 0.75])
    
        # Retrieve the minimal and most values of the variable
        vmin = knowledge[variable].min()
        vmax = knowledge[variable].max()
    
        # Outline the bin edges
        # A small epsilon is subtracted from the minimal worth to make sure it's included
        bins = [vmin - 1e-9, q1, q2, q3, vmax]
    
        # Outline human-readable labels for every interval
        labels = [
            f"]{vmin:.2f} ; {q1:.2f}]",
            f"]{q1:.2f} ; {q2:.2f}]",
            f"]{q2:.2f} ; {q3:.2f}]",
            f"]{q3:.2f} ; {vmax:.2f}]",
        ]
    
        # Use pandas.minimize to assign every remark to a quartile-based interval
        knowledge[new_var] = pd.minimize(
            knowledge[variable],
            bins=bins,
            labels=labels,
            include_lowest=True
        )
    
        # Return the dataframe with the brand new discretized variable
        return knowledge

    Instance of utility for a steady variable

    # Distribution by age (person_age)
    # Discretize the variable into quartiles
    
    df_with_age_bins = create_quartile_bins(
        df,
        variable="person_age",
        new_var="age_quartile"
    )
    
    abstract = generate_categorical_report_excel(
        df=df_with_age_bins,
        category_col="age_quartile",
        default_col="def",
        output_path="age_quartile_report.xlsx",
        sheet_name="Age Quartiles",
        title="Distribution by Age (Quartiles)",
        category_label="Age Quartiles",
        sort_by="default_rate",
        ascending=False
    )



    Source link

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Editor Times Featured
    • Website

    Related Posts

    I Built a C++ Backend So My GPU Would Stop Eating Air

    June 3, 2026

    I Spent May Evaluating Different Engines for OCR

    June 3, 2026

    Why AI Is NOT Stealing Your Job

    June 3, 2026

    What AI Agents Should Never Do on Their Own

    June 3, 2026

    Exploring Income Patterns with Python Pandas, Matplotlib, and Seaborn

    June 2, 2026

    From Local App to Public Website in Minutes

    June 2, 2026

    Comments are closed.

    Editors Picks

    June deadline approaches for Hawthorne sale process

    June 4, 2026

    Today’s NYT Mini Crossword Answers for June 4

    June 4, 2026

    New tiny nudibranch species discovered in Taiwan

    June 4, 2026

    Why the Budget’s CGT changes are a disaster for angel investors and startups

    June 4, 2026
    Categories
    • Founders
    • Startups
    • Technology
    • Profiles
    • Entrepreneurs
    • Leaders
    • Students
    • VC Funds
    About Us
    About Us

    Welcome to Times Featured, an AI-driven entrepreneurship growth engine that is transforming the future of work, bridging the digital divide and encouraging younger community inclusion in the 4th Industrial Revolution, and nurturing new market leaders.

    Empowering the growth of profiles, leaders, entrepreneurs businesses, and startups on international landscape.

    Asia-Middle East-Europe-North America-Australia-Africa

    Facebook LinkedIn WhatsApp
    Featured Picks

    I Tested MSI’s $999 Gaming Laptop and Liked Its 1080p Performance but Little Else

    August 21, 2025

    FanDuel Casino launches Love Island slot game in select US states

    December 11, 2025

    9 Best Speakers for Kids (2025): Smart, Bluetooth, and Offline Speakers

    November 25, 2025
    Categories
    • Founders
    • Startups
    • Technology
    • Profiles
    • Entrepreneurs
    • Leaders
    • Students
    • VC Funds
    Copyright © 2024 Timesfeatured.com IP Limited. All Rights.
    • Privacy Policy
    • Disclaimer
    • Terms and Conditions
    • About us
    • Contact us

    Type above and press Enter to search. Press Esc to cancel.