Code
from toolz import filter
numbers = [1, 2, 3, 4, 5]
result = list(filter(lambda x: x > 3, numbers))
print(result) # Output: [4, 5]
toolzThe toolz library enhances Python’s functional programming (FP) capabilities, offering tools for writing concise, modular, and reusable code. Inspired by functional languages like Clojure, toolz provides utilities for working with iterables, dictionaries, and functions, complementing Python’s built-in map, filter, and functools.reduce. This tutorial introduces toolz, highlights its key functions, and applies them to analyze a dataset of lung and bronchus cancer mortality rates (1998–2010) with covariates like smoking prevalence, poverty rates, and air pollutants (PM2.5, NO2, SO2).
toolzInstall toolz and other required packages for this tutorial.
toolztoolz is a Python library for functional programming, organized into modules:
toolz.itertoolz: Functions for iterables (e.g., filter, partition, groupby).toolz.functoolz: Function manipulation (e.g., compose, curry).toolz.dicttoolz: Dictionary operations (e.g., merge, keyfilter).Unlike Python’s built-in map and filter, toolz functions are designed for composability and often provide more flexible or specialized behavior. Key benefits include:
toolz functions return iterators, improving efficiency for large datasets.toolz FunctionsBelow are key toolz functions used in this tutorial, with examples.
toolz.filter: Filtering IterablesSimilar to Python’s filter, but integrates well with toolz pipelines.
Example: Filter numbers greater than 3.
toolz.reduce: Reducing IterablesSimilar to functools.reduce, but designed for functional pipelines.
Example: Sum squares of numbers.
toolz.compose: Function CompositionCombines multiple functions into a single function, applying them from right to left.
Example: Compose functions to add 1 and double.
toolz.curry: Partial Function ApplicationCreates a new function with some arguments pre-filled.
Example: Create a function to multiply by a fixed number.
toolz.groupby: Grouping DataGroups an iterable by a key function, similar to pandas.groupby but for iterables.
Example: Group numbers by parity.
We apply toolz to a dataset of age-adjusted lung and bronchus cancer mortality rates (1998–2010) with covariates (smoking prevalence, poverty rates, PM2.5, NO2, SO2). The workflow includes loading data, splitting by year, computing statistics, and visualizing correlations.
Year: Year of observation (1998–2010).SMOKING: Smoking prevalence (%).POVERTY: Poverty rate (%).PM25, NO2, SO2: Air pollutant concentrations.RATE: Age-adjusted mortality rate.Note: Column names are assumed based on context. Adjust if inspection reveals different names.
Use Python’s map to iterate over years and write subsets to CSV files.
import glob
import re
from toolz import groupby
import pandas as pd
import os
# Ensure correct working directory
os.chdir('/home/zia207/Dropbox/WebSites/GitHub/python-colab/NoteBook/Python_for_Beginners/output')
# Select numeric columns
def select_numeric_cols(df):
expected_cols = ['SMOKING', 'POVERTY', 'PM25', 'NO2', 'SO2', 'RATE']
if not all(col in df.columns for col in expected_cols):
missing = [col for col in expected_cols if col not in df.columns]
raise ValueError(f"Missing columns in DataFrame: {missing}")
return df[expected_cols]
# List all CSV files
files = glob.glob('data_*.csv')
if not files:
raise FileNotFoundError('No CSV files found in output directory.')
# Create a list of (year, DataFrame) tuples with validation
year_data = []
for f in files:
year = re.search(r'\d{4}', f).group()
try:
df = pd.read_csv(f)
if df.empty:
print(f"Warning: {f} is empty, skipping.")
continue
year_data.append((year, select_numeric_cols(df)))
except Exception as e:
print(f"Error reading {f}: {e}")
# Print year_data to check for duplicates
print("year_data:", [(year, id(df)) for year, df in year_data]) # Use id(df) to distinguish DataFramestoolz.groupbyRead CSV files and group data by year using toolz.groupby.
import glob
import re
from toolz import groupby
import pandas as pd
# Group by year using toolz.groupby
data_list = dict(groupby(lambda x: x[0], year_data))
# Print grouped data to inspect structure
print("Grouped data:", {year: [(y, id(df)) for y, df in group] for year, group in data_list.items()})
# Convert to desired format (handle single DataFrame per year)
data_list = {year: group[0][1] for year, group in data_list.items() if group} # Take first DataFrame
print(f'Loaded {len(data_list)} datasets for years: {list(data_list.keys())}')toolz.reduceCalculate mean and standard deviation for numeric columns using toolz.reduce.
from toolz import reduce
import numpy as np
def compute_stats(df, year):
stats_dict = {'Year': year}
for col in df.columns:
values = df[col].dropna()
mean = reduce(lambda x, y: x + y, values) / len(values)
variance = reduce(lambda acc, x: acc + (x - mean)**2, values, 0) / len(values)
stats_dict.update({
f'{col}_Mean': mean,
f'{col}_Std': np.sqrt(variance)
})
return pd.DataFrame(stats_dict, index=[0])
stats_df = pd.concat([compute_stats(df, year) for year, df in data_list.items()])
stats_df = stats_df.round(3)
print('Descriptive Statistics:\n', stats_df)toolz.filterCompute correlations and filter those with p-values < 0.05.
from scipy import stats
from toolz import filter
def compute_correlations(df, year):
predictors = ['SMOKING', 'POVERTY', 'PM25', 'NO2', 'SO2']
correlations = [
{'Year': year, 'Variable': var, 'r': stats.pearsonr(df['RATE'], df[var])[0],
'p_value': stats.pearsonr(df['RATE'], df[var])[1]}
for var in predictors
]
# Filter significant correlations (p < 0.05)
significant = list(filter(lambda x: x['p_value'] < 0.05, correlations))
return pd.DataFrame(significant)
cor_table = pd.concat([compute_correlations(df, year) for year, df in data_list.items()])
cor_table = cor_table.round(3)
print('Significant Correlations (p < 0.05):\n', cor_table)toolz.composeUse compose to create a plotting function that combines data processing and visualization.
import matplotlib.pyplot as plt
import seaborn as sns
# Define plotting function
def plot_cor_matrix(df):
cor_matrix = df.corr()
sns.heatmap(cor_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, center=0)
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
# Plotting function with title
def plot_with_title(df, year):
plot_cor_matrix(df)
plt.title(f'Correlation Matrix - {year}')
# Create a 5x3 grid of subplots
fig, axes = plt.subplots(5, 3, figsize=(12, 15))
axes = axes.flatten()
# Plot correlation matrices
for i, (year, df) in enumerate(sorted(data_list.items())): # Sort for consistent order
if i < len(axes): # Ensure we don't exceed subplot count
plt.sca(axes[i])
plot_with_title(df, year)
else:
break
# Hide unused subplots
for i in range(len(data_list), len(axes)):
axes[i].set_visible(False)
plt.suptitle('Correlation Matrices by Year', y=1.02)
plt.tight_layout()
plt.show()This tutorial demonstrated how toolz enhances functional programming in Python through functions like filter, reduce, compose, curry, and groupby. Applied to a cancer mortality dataset, toolz enabled a clean, modular workflow for splitting data, computing statistics, filtering significant correlations, and visualizing results. Combined with pandas and seaborn, toolz provides a powerful toolkit for functional data analysis.
toolz.pandas for data analysis.