Statistics Operations
The iterable.ops.stats module provides functions for computing statistics, frequency analysis, and unique value detection on datasets.
Overview
Statistics operations help you understand data distributions and patterns:
- Compute comprehensive statistics for all fields
- Analyze frequency distributions of values
- Detect unique values and duplicates
- Leverage DuckDB for fast computation on large datasets
Functions
compute()
Compute comprehensive statistics for all fields in an iterable dataset.
from iterable.ops import stats
# Compute statistics for a file
summary = stats.compute("data.csv", detect_dates=True)
print(summary["price"]["mean"])
print(summary["price"]["stddev"])
# Compute statistics for an iterable
rows = [
{"value": 1, "name": "a"},
{"value": 2, "name": "b"},
{"value": 3, "name": "c"},
]
summary = stats.compute(rows)
Parameters:
iterable: An iterable of row dictionaries, or a file path/streamdetect_dates: Whether to detect date fields (default: False)engine: Optional engine to use ('duckdb' for optimization)include_top_values: When True, includetop_values(most frequent values with counts) per field (default: False)top_n: Number of top values to include wheninclude_top_valuesis True (default: 10)dict_threshold: Unique-to-total ratio at/below which a field is flagged as a dictionary (lookup) field. Defaults to theDICT_THRESHOLDenvironment variable or 0.1.
Returns: Dictionary mapping field names to their statistics:
count: Number of non-null valuesnull_count: Number of null valuesnull_fraction: Fraction of values that are null (0..1)unique_count: Number of unique valuesis_dictionary: Whether the field behaves as a dictionary/lookup fieldtop_values: List of{value, count}(only wheninclude_top_values=True)min,max: Minimum and maximum values (for numeric fields)mean,median,stddev: Statistical measures (for numeric fields)min_length,max_length,avg_length: String length statistics (for string fields)
Example Output:
{
"price": {
"count": 1000,
"null_count": 5,
"unique_count": 250,
"min": 10.0,
"max": 999.99,
"mean": 245.5,
"median": 200.0,
"stddev": 150.2
},
"name": {
"count": 1000,
"null_count": 0,
"unique_count": 500,
"min_length": 3,
"max_length": 50,
"avg_length": 12.5
}
}
frequency()
Compute frequency distributions for specified fields.
from iterable.ops import stats
# Frequency analysis for single field
freq = stats.frequency("data.csv", fields=["status"])
print(freq["status"]["active"]) # Count of "active" status
# Frequency analysis for multiple fields
freq = stats.frequency("data.csv", fields=["status", "category"])
# Frequency with limit (top N most frequent)
freq = stats.frequency("data.csv", fields=["status"], limit=10)
Parameters:
iterable: An iterable of row dictionaries, or a file path/streamfields: List of field names to analyze (None for all fields)limit: Optional limit on number of top frequencies to return per field
Returns: Dictionary mapping field names to frequency dictionaries (value -> count, sorted by frequency descending)
Example Output:
{
"status": {
"active": 750,
"inactive": 200,
"pending": 50
},
"category": {
"A": 400,
"B": 300,
"C": 300
}
}
uniq()
Identify unique rows or unique values for specified fields.
from iterable.ops import stats
# Get unique rows by email
unique_rows = list(stats.uniq("data.csv", fields=["email"]))
# Get unique values only
unique_emails = list(stats.uniq("data.csv", fields=["email"], values_only=True))
# Get unique values with counts
counts = stats.uniq("data.csv", fields=["email"], include_count=True)
print(counts["user@example.com"]) # Count of occurrences
Parameters:
iterable: An iterable of row dictionaries, or a file path/streamfields: List of field names to use for uniqueness (None for all fields)values_only: If True, return only unique values (not full rows)include_count: If True, include occurrence counts in results
Returns:
- If
values_only=True: Iterator of unique values - If
include_count=True: Dictionary mapping unique items to counts - Otherwise: Iterator of unique rows
Examples
Basic Statistics
from iterable.ops import stats
# Compute statistics for all fields
summary = stats.compute("sales.csv", detect_dates=True)
# Access statistics for a field
price_stats = summary["price"]
print(f"Price range: ${price_stats['min']:.2f} - ${price_stats['max']:.2f}")
print(f"Average price: ${price_stats['mean']:.2f}")
print(f"Standard deviation: ${price_stats['stddev']:.2f}")
print(f"Unique prices: {price_stats['unique_count']}")
Frequency Analysis
from iterable.ops import stats
# Find most common status values
freq = stats.frequency("users.csv", fields=["status"], limit=5)
print("Top 5 statuses:")
for status, count in freq["status"].items():
print(f" {status}: {count}")
# Analyze multiple fields
freq = stats.frequency("products.csv", fields=["category", "brand"])
for field, frequencies in freq.items():
print(f"\n{field} distribution:")
for value, count in list(frequencies.items())[:5]: # Top 5
print(f" {value}: {count}")
Finding Duplicates
from iterable.ops import stats
# Find unique emails
unique_emails = list(stats.uniq("users.csv", fields=["email"], values_only=True))
print(f"Unique emails: {len(unique_emails)}")
# Find duplicate emails with counts
email_counts = stats.uniq("users.csv", fields=["email"], include_count=True)
duplicates = {email: count for email, count in email_counts.items() if count > 1}
print(f"Duplicate emails: {len(duplicates)}")
for email, count in duplicates.items():
print(f" {email}: {count} occurrences")
Data Quality Analysis
from iterable.ops import stats
# Analyze data quality
summary = stats.compute("data.csv")
for field, stats_info in summary.items():
null_pct = (stats_info["null_count"] /
(stats_info["count"] + stats_info["null_count"]) * 100)
print(f"{field}:")
print(f" Null percentage: {null_pct:.1f}%")
print(f" Unique values: {stats_info['unique_count']}")
if "mean" in stats_info:
print(f" Range: {stats_info['min']} - {stats_info['max']}")
print(f" Mean: {stats_info['mean']:.2f}")
Combining with Other Operations
from iterable.ops import inspect, stats, transform
# Analyze a sample of data
sample = list(transform.sample_rows("large_dataset.csv", n=10000))
summary = stats.compute(sample)
# Get frequency of top categories
freq = stats.frequency(sample, fields=["category"], limit=10)
# Find unique combinations
unique = list(stats.uniq(sample, fields=["user_id", "product_id"]))
print(f"Unique user-product combinations: {len(unique)}")
Performance Notes
compute(): For large files, consider usingengine="duckdb"for significant performance improvementsfrequency(): Efficient streaming implementation, handles large datasets welluniq(): Memory-efficient for unique value detection, but may require full iteration
Integration with DuckDB
When available, DuckDB can significantly speed up statistics computation:
from iterable.ops import stats
# Fast statistics with DuckDB (for CSV/JSONL/JSON/Parquet)
try:
summary = stats.compute("large_file.csv", engine="duckdb")
except Exception:
# Falls back to Python implementation
summary = stats.compute("large_file.csv")
Type Detection
The compute() function automatically detects field types:
- Numeric fields: Get min, max, mean, median, stddev
- String fields: Get min_length, max_length, avg_length
- Date fields: Enable with
detect_dates=Truefor date-specific statistics