irf23/canadian-parliamentary-expenditures
Canadian House of Commons Parliamentary Expenditures Dataset This dataset contains detailed expenditure records from the Canadian House of Commons, spanning from 2021 Q2 to 2025 Q4, with 1,219,648 total expenditure records across 450 parliament members. Dataset Structure parliamentary_data_hf/ ├── data/ │ ├── train/ # Training split (2021-2024) │ │ ├── expenditures-2021-q2.parquet │ │ ├── expenditures-2021-q3.parquet │ │ ├── ...… See the full description on the dataset page: https://huggingface.co/datasets/irf23/canadian-parliamentary-expenditures.
Canadian House of Commons Parliamentary Expenditures Dataset
This dataset contains detailed expenditure records from the Canadian House of Commons, spanning from 2021 Q2 to 2025 Q4, with 1,219,648 total expenditure records across 450 parliament members.
Dataset Structure
parliamentary_data_hf/
├── data/
│ ├── train/ # Training split (2021-2024)
│ │ ├── expenditures-2021-q2.parquet
│ │ ├── expenditures-2021-q3.parquet
│ │ ├── ... # All quarters from 2021-2024
│ │ ├── expenditures-2024-q4.parquet
│ │ └── members.parquet # Parliament member records
│ └── test/ # Test split (2025)
│ ├── expenditures-2025-q1.parquet
│ ├── expenditures-2025-q2.parquet
│ ├── expenditures-2025-q3.parquet
│ ├── expenditures-2025-q4.parquet
│ └── members.parquet # Parliament member records
├── analytics.json # Analytics metadata
└── metadata.json # Dataset metadataData Statistics
- Total Records: 1,219,648 expenditures
- Total Members: 450 parliament members
- Time Period: 2021 Q2 to 2025 Q4 (19 quarters)
- Parties: Liberal (534,383 records), Conservative (426,037), NDP (82,187), BlocQuebecois (153,319), Independent (17,437), Green (6,285)
- Categories: Travel, Hospitality, Contract
- File Sizes: From 474B (2019 Q2) to 67MB (2024 Q4)
Data Format
Expenditure Records
Each expenditure record contains:
Id: Unique identifierMemberId: UUID of the memberMemberName: Full name of the memberConstituency: Electoral districtParty: Political party (Liberal, Conservative, NDP, BlocQuebecois, Green, Independent)Category: Type of expenditure (Travel, Hospitality, Contract, Other)Amount: Dollar amountDescription: Description of the expenditureLocation: Location of expenditureSupplier: Vendor/supplier namePeriodYear: Fiscal yearPeriodQuarter: Fiscal quarter (1-4)ReportingPeriodYear: Reporting period yearReportingPeriodQuarter: Reporting period quarterDateIncurred: Date when expense was incurredClaimId: Claim reference numberCreatedAt: Record creation timestampUpdatedAt: Record update timestamp
Members Data
Each member record contains:
MemberId: Unique identifierName: Full nameConstituency: Electoral districtParty: Political party affiliationProvince: Province codeIsActive: Whether currently servingCreatedAt: Record creation timestampUpdatedAt: Record update timestamp
Data Format
The dataset uses Parquet format, which provides:
- Efficient columnar storage with excellent compression
- Fast loading and querying performance
- Native support in pandas, PySpark, and other data tools
- Individual quarterly files for selective loading
- A combined file (
expenditures.parquet) with all records - Strong typing and schema preservation
Usage
Loading Parquet Data
import pandas as pd
from pathlib import Path
# Load all training data
train_files = list(Path('data/train').glob('expenditures-*.parquet'))
train_df = pd.concat([pd.read_parquet(f) for f in train_files])
print(f"Training records: {len(train_df)}")
# Load test data
test_files = list(Path('data/test').glob('expenditures-*.parquet'))
test_df = pd.concat([pd.read_parquet(f) for f in test_files])
print(f"Test records: {len(test_df)}")
# Load members data
members_df = pd.read_parquet('data/train/members.parquet')
print(f"Total members: {len(members_df)}")
# Load a specific quarter
q1_2024 = pd.read_parquet('data/train/expenditures-2024-q1.parquet')
print(f"Q1 2024: {len(q1_2024)} records")Working with Analytics Data
import json
# Load analytics metadata
with open('analytics.json', 'r') as f:
analytics = json.load(f)
# View summary statistics
print(f"Total records: {analytics['total_records']}")
print(f"Date range: {analytics['date_range']['start']} to {analytics['date_range']['end']}")Analysis Examples
# Total spending by party (using training data)
party_spending = train_df.groupby('Party')['Amount'].sum().sort_values(ascending=False)
# Top spenders across all data
all_df = pd.concat([train_df, test_df])
top_spenders = all_df.groupby('MemberName')['Amount'].sum().nlargest(20)
# Spending trends over time
quarterly_spending = all_df.groupby(['PeriodYear', 'PeriodQuarter'])['Amount'].sum()
# Category breakdown
category_breakdown = all_df.groupby('Category')['Amount'].agg(['sum', 'count', 'mean'])
# Join with members data
merged_df = train_df.merge(members_df, on='MemberId', suffixes=('', '_member'))Loading with Hugging Face Datasets
from datasets import load_dataset
# Load the complete dataset
dataset = load_dataset('irf23/canadian-parliamentary-expenditures')
# Access expenditures and members
expenditures = dataset['expenditures']
members = dataset['members']Data Quality Notes
- Some records may have negative amounts (adjustments/corrections)
- Party affiliations are now correctly mapped from the members data (previously all showed as "Other")
- All amounts are in Canadian dollars (CAD)
- Date fields use ISO 8601 format with timezone information
- A data entry error where year 2024 was recorded as 224 has been corrected
License
This dataset is compiled from publicly available government data from the House of Commons of Canada. The original data is in the public domain.
