sidetable

repository·master·Indexed 19 days ago

https://github.com/chris1610/sidetable

A library that extends pandas DataFrames with a `.stb` accessor to simplify the creation of summary tables. It provides tools for building frequency tables via `.stb.freq()`, analyzing missing values with `.stb.missing()`, adding subtotals and grand totals using `.stb.subtotal()`, flattening MultiIndex columns with `.stb.flatten()`, and formatting numeric results with `.stb.pretty()`. Requires pandas 1.0 or higher.

Tokens
3K
Snippets
16
Records
17
Agent score
14%

What's inside sidetable

  1. Handling high-cardinality data in sidetable

    master

    sidetable supports grouping on any data type. However, if you attempt to run .stb.freq() on a column with a large number of unique values (high cardinality), the resulting table may be too large to be useful.

    To resolve this, you should bin the continuous data into discrete categories using pandas methods like pd.qcut or pd.cut before calling sidetable functions.

    # Instead of this (if 'fare' has many unique values):
    # df.stb.freq(['fare'])
    
    # Do this:
    df['fare_bin'] = pd.qcut(df['fare'], q=4, labels=['low', 'medium', 'high', 'x-high'])
    df.stb.freq(['fare_bin'])
  2. How sidetable integrates with pandas

    master

    sidetable uses the pandas DataFrame accessor API to add a .stb accessor to all your DataFrames. Once you import sidetable, the .stb property becomes available on any pandas DataFrame instance, allowing you to call sidetable methods directly on your data.

    import pandas as pd
    import sidetable
    
    # Now df.stb is available
    df = pd.DataFrame({'a': [1, 2, 3]})
  3. How sidetable works with pandas

    master

    sidetable extends pandas DataFrames by adding a new .stb accessor. Once you import sidetable, all pandas DataFrame objects will have access to the .stb namespace for performing summary tasks like frequency tables, missing value analysis, and subtotals.

    import sidetable
    import pandas as pd
    
    df = pd.read_csv('myfile.csv')
    # Access sidetable features via the .stb accessor
    df.stb.freq(['column1'])
  4. Handling missing values (NaN) in sidetable

    master

    By default, null or missing values may cause data to drop out during aggregation in sidetable. This means the cumulative_count in your frequency table might not match the total number of rows in your original DataFrame.

    To include missing values in your frequency tables, you should handle them explicitly in your DataFrame (e.g., using .fillna()) before calling sidetable methods. If working with Categorical data, you must first add the new category to the column's categories before filling.

    # For standard columns:
    # df['col'] = df['col'].fillna('UNK')
    
    # For Categorical columns:
    df['deck_fillna'] = df['deck'].cat.add_categories('UNK').fillna('UNK')
    df.stb.freq(['deck_fillna'])
  5. Flatten multiindex DataFrames with `stb.flatten()`

    master

    When working with complex grouping or pivoting (like unstack()), you often end up with a MultiIndex. flatten() converts this into a simple, flat representation.

    Options:

    • sep: Define a custom string to use as a separator in the new column names (e.g., sep='|').
    • reset: Boolean to control whether to reset the index.
    • levels: An integer or a list of levels to reorganize the output display.
    # Flatten a multiindex DataFrame
    complex_df = df.groupby(['embark_town', 'class', 'sex']).agg({'fare': ['sum'], 'age': ['mean']}).unstack()
    complex_df.stb.flatten()
    
    # Flatten with custom separator and specific level reorganization
    complex_df.stb.flatten(sep='|', reset=False, levels=[0, 2])
  6. Build frequency tables with `stb.freq()`

    master

    The freq() method creates a frequency table for one or more columns. It provides counts, percentages, and cumulative totals, which is much simpler than manually combining value_counts() results in pandas.

    Key Features:

    • Grouping: Pass a list of columns to group by multiple levels (e.g., df.stb.freq(['sex', 'class'])).
    • Styling: Use style=True to format percentages and large numbers for better readability.
    • Summing Values: Use the value argument to sum data from another column instead of just counting occurrences (e.g., df.stb.freq(['class'], value='fare')).
    • Thresholding: Use thresh to group low-frequency entries into an "other" category. You can customize this label with other_label.
    # Basic frequency table
    df.stb.freq(['class'])
    
    # Styled frequency table
    df.stb.freq(['class'], style=True)
    
    # Grouping multiple columns
    df.stb.freq(['sex', 'class'])
    
    # Summing a specific column (e.g., fare) by group
    df.stb.freq(['class'], value='fare')
    
    # Using a threshold to group small entries into 'All others'
    df.stb.freq(['class', 'who'], value='fare', thresh=80, other_label='All others')
  7. Add subtotals to grouped data with `stb.subtotal()`

    master

    The subtotal() method allows you to add subtotal rows to a DataFrame, which is particularly useful for grouped pandas data.

    Usage Patterns:

    • Grand Total: Calling df.stb.subtotal() on a simple DataFrame adds a 'grand_total' row.
    • Grouped Subtotals: When used on a grouped DataFrame, it adds subtotals at the specified levels.
    • Controlling Levels: Use sub_level=[...] to specify exactly which levels should receive a subtotal.
    • Customization: Use grand_label, sub_label, show_sep, and sep to configure labels and separators.
    # Add a grand total to a simple DataFrame
    df.stb.subtotal()
    
    # Add subtotals at specific levels of a grouped DataFrame
    summary_table = df.groupby(['sex', 'class', 'embark_town']).agg({'fare': ['sum']})
    summary_table.stb.subtotal(sub_level=[1, 2])
  8. Show all combinations including zero counts with clip_0=False

    master

    When performing frequency analysis on multiple columns, sidetable only shows combinations that actually exist in the data. If you want to see all possible combinations—including those with zero occurrences—pass the clip_0=False argument to the .freq() method.

    # Shows only existing combinations
    # df.stb.freq(['deck', 'class'])
    
    # Shows all combinations, including those with 0 counts
    df.stb.freq(['deck', 'class'], clip_0=False)
  9. Summarize column statistics with `stb.counts()`

    master

    The counts() method provides a high-level summary of each column, including the total count, number of unique values, most frequent value (and its count), and least frequent value (and its count). This is useful for understanding data structure and identifying potential categorical conversions.

    You can filter which columns are included using include or exclude parameters, following the same syntax as pandas select_dtypes.

    # Summary of all columns
    df.stb.counts()
    
    # Exclude numeric columns from the summary
    df.stb.counts(exclude='number')
  10. Format numeric results with `stb.pretty()`

    master

    The pretty() method interprets the magnitude of numeric results and returns a formatted version (e.g., converting 9975.825 to 9.98k). This is ideal for making aggregated data or large numbers easier to read in reports.

    Options:

    • precision: Control the number of decimal places.
    • rows: Control the number of rows displayed.
    • caption: Add a title/caption to the resulting table.
    # Format aggregated sums nicely
    df.groupby(['pclass', 'sex']).agg({'fare': 'sum'}).stb.pretty()
    
    # Format as percentages with custom precision and caption
    df.groupby(['pclass', 'sex']).agg({'fare': 'sum'}).div(df['fare'].sum()).stb.pretty(precision=0, caption="Fare Percentage")