Contents
Deep Breakdown
What it tells me (Situation Awareness): Multiplying fractions is the most direct of the four fraction operations: multiply numerators together, multiply denominators together. . No common denominator required. In DA/DS, fraction multiplication appears in: compound probabilities ( for independent events), scaling a proportion by a rate (e.g., 20% of 15% of users), chained conversion rates through a funnel, dimensional unit conversions, and computing the fraction of a fraction (e.g., "what fraction of premium users who opened the email also clicked?"). The simplicity of the formula makes it easy to apply in code — it is just ordinary multiplication — but the interpretation requires care: means "take of the quantity ", so the result is always smaller than or equal to both operands when both are proper fractions ().
Flowchart
Real-world use
Where it is used
Funnel analysis: of site visitors click an ad (), and of those convert (). The overall conversion rate is . Probability: under independence, . Scaling: if a model predicts a 40% conversion probability and the base rate is 15%, the expected fraction is . Unit conversion: converting of a rate expressed in to a per-minute rate involves multiplying by .
Problem it solves
Chaining rates or proportions without fraction multiplication leads to either summing (wrong) or confusing the result. The "fraction of a fraction" question — "what is of ?" — translates directly to multiplication and gives a result in the same unit as the original fractions.
How it solves the problem
: no common denominator needed. Numerators multiply together, denominators multiply together. The result is a valid fraction that can be simplified by dividing numerator and denominator by . An optimization: cross-cancel before multiplying — if , simplify first; if , simplify first. This avoids large intermediate numbers.
Example in a business
Email funnel: a mailing list has deliverability (80% delivered). Of delivered emails, are opened (25% open rate). Of opened emails, have a link clicked (33% CTR). The end-to-end click rate per email sent: . Each stage is a fraction of the previous, and the chain is just repeated multiplication.
The formula, piece by piece
Breaking the notation:
- : numerator of the first fraction — the part being considered.
- : denominator of the first fraction — the reference whole.
- : multiplication symbol (also written or with no symbol when using adjacent fraction notation).
- : numerator of the second fraction.
- : denominator of the second fraction.
- : product of the two numerators.
- : product of the two denominators.
- : the result — a fraction of a fraction. Interpretation: asks "what is of ?" The result is always when both fractions are in — multiplying proper fractions always makes the result smaller. Cross-cancellation (simplification before multiplying):
Apply the same idea across the - pair with . Extending to three fractions: .
The formula in words
"To multiply by : just multiply the tops together to get the new top, and the bottoms together to get the new bottom. No common denominator needed. Simplify the result. In code it is just (a * c) / (b * d) in float, or Fraction(a, b) * Fraction(c, d) for exact arithmetic. Multiplying fractions always shrinks the result (when both are between 0 and 1) — you are taking a fraction of a fraction."
Critical Concepts
- No common denominator needed: unlike addition and subtraction, fraction multiplication requires no denominator matching. This makes it faster and simpler. Never convert to a common denominator before multiplying.
- Cross-cancellation reduces work: simplify and before multiplying to avoid large numerators and denominators in intermediate steps. Example: — cross-cancel 4 with 8 (÷4) and 3 with 9 (÷3) to get , rather than computing and reducing.
- Multiplying by a fraction < 1 shrinks the value: whenever . This is the mathematical basis for why each funnel step reduces the number of users.
- Compound probability and independence: holds only for independent events. Fraction multiplication computes the product — whether it represents a valid joint probability depends on your independence assumption, not on the arithmetic.
- Fractions of percentages: in Python, when both values are given as percentages (e.g.,
0.30 * 0.25), you are already computing the fraction multiplication in decimal form.0.30 * 0.25 = 0.075 = 7.5%.
Always check whether you should multiply or add — "30% AND 25%" (joint/compound) multiplies; "30% OR 25%" (union, mutually exclusive) adds.
Step-by-step calculation (tiny example)
Task: email funnel — deliverability × open rate × CTR.
Step 1: Write each stage as a fraction Deliverability = , open rate = , CTR = .
Step 2: Cross-cancel where possible : — cancel: . Now multiply result by : .
Step 3: Interpret the result end-to-end click rate.
Step 4: Verify without cancellation .
Code examples
Beginner example (Python)
# Fraction multiplication in Python
from fractions import Fraction
# Basic: a/b × c/d
a, b = 3, 10 # 30% click-through on ad
c, d = 1, 4 # 25% conversion of those who click
numerator = a * c # ac
denominator = b * d # bd
print(f"Manual: ({a}×{c}) / ({b}×{d}) = {numerator}/{denominator} = {numerator/denominator:.4f}")
# Python Fraction (auto-simplifies)
frac_1 = Fraction(a, b)
frac_2 = Fraction(c, d)
result = frac_1 * frac_2
print(f"Fraction class: {frac_1} × {frac_2} = {result} ({float(result):.4f})")
print(f"Simplified: {float(result):.1%}")
# Funnel chain: 3 stages
deliverability = Fraction(4, 5) # 80%
open_rate = Fraction(1, 4) # 25%
ctr = Fraction(1, 3) # 33%
end_to_end = deliverability * open_rate * ctr
print(f"\nFunnel chain:")
print(f" deliverability × open rate × CTR")
print(f" {deliverability} × {open_rate} × {ctr} = {end_to_end} = {float(end_to_end):.4f}")
# Compound probability (independent events)
import numpy as np
np.random.seed(42)
N = 100_000
# Simulate: P(A) = 0.3, P(B) = 0.25, independent
event_a = np.random.rand(N) < 0.30
event_b = np.random.rand(N) < 0.25
both_occur = (event_a & event_b).mean()
theoretical = 0.30 * 0.25 # fraction multiplication
print(f"\nCompound probability (independent):")
print(f" P(A) × P(B) = 0.30 × 0.25 = {theoretical:.4f}")
print(f" Simulated P(A ∩ B) = {both_occur:.4f} (close to {theoretical:.4f})")Beginner example (R)
# Fraction multiplication in R
# Basic fraction multiplication
a <- 3; b <- 10 # 30%
c <- 1; d <- 4 # 25%
numerator <- a * c
denominator <- b * d
cat(sprintf("(%d×%d) / (%d×%d) = %d/%d = %.4f\n", a, c, b, d, numerator, denominator, numerator / denominator))
# Simplify with GCD
gcd <- function(x, y) if (y == 0) x else gcd(y, x %% y)
g <- gcd(numerator, denominator)
cat(sprintf("Simplified: %d/%d\n", numerator / g, denominator / g))
# Funnel chain
deliverability <- 4/5
open_rate <- 1/4
ctr <- 1/3
end_to_end <- deliverability * open_rate * ctr
cat(sprintf("\nFunnel chain: %.4f × %.4f × %.4f = %.4f (%.1f%%)\n", deliverability, open_rate, ctr, end_to_end, end_to_end * 100))
# Compound probability simulation
set.seed(42)
N <- 100000
p_a <- 0.30
p_b <- 0.25
event_a <- runif(N) < p_a
event_b <- runif(N) < p_b
theoretical <- p_a * p_b
simulated <- mean(event_a & event_b)
cat(sprintf("\nP(A) × P(B) = %.4f | Simulated: %.4f\n", theoretical, simulated))Professional example (Python)
import pandas as pd
import numpy as np
from fractions import Fraction
from typing import List # Scenario: multi-stage marketing funnel audit
# Each stage is a conversion fraction; end-to-end rate = product of all fractions
# Also computes exact fractions from count data and flags stages below threshold
np.random.seed(42) # Simulate count data for each funnel stage
impressions = 100_000
clicks = 32_000 # 32% CTR
page_visits = 25_000 # 78.1% of clicks visit landing page
add_to_cart = 6_000 # 24% add to cart
checkouts = 2_400 # 40% checkout
purchases = 1_800 # 75% complete purchase
funnel_counts = [ ("impressions → clicks", impressions, clicks), ("clicks → page_visits", clicks, page_visits), ("page_visits → add_to_cart", page_visits, add_to_cart), ("add_to_cart → checkouts", add_to_cart, checkouts), ("checkouts → purchases", checkouts, purchases),
]
THRESHOLD = Fraction(1, 5) # flag stages below 20%
def compute_funnel_product(stages: list[tuple]) -> pd.DataFrame:
""" Compute conversion rate for each funnel stage and the end-to-end product. Args: stages: List of (label, input_count, output_count) tuples. Returns: DataFrame with stage label, fraction, float rate, and flag. """
rows = []
cumulative = Fraction(1)
for label, n_in, n_out in stages:
rate = Fraction(n_out, n_in)
cumulative *= rate
rows.append({ "stage": label, "fraction": str(rate), "rate": float(rate), "below_20pct": rate < THRESHOLD, "cumulative": float(cumulative), })
return pd.DataFrame(rows)
report = compute_funnel_product(funnel_counts)
print("Funnel Audit: Stage Conversion Rates (fraction multiplication)")
print("=" * 72)
print(report.to_string(index=False)) # End-to-end rate = product of all stage fractions
rates = [Fraction(n_out, n_in) for _, n_in, n_out in funnel_counts]
end_to_end = Fraction(1)
for r in rates:
end_to_end *= r
print(f"\nEnd-to-end conversion (impressions → purchases):")
print(f" {' × '.join(str(r) for r in rates)}")
print(f" = {end_to_end} = {float(end_to_end):.4f} ({float(end_to_end):.2%})")
print(f"\nDirect count check: {purchases}/{impressions} = {Fraction(purchases, impressions)} = {purchases/impressions:.4f}")
print(f"Match: {end_to_end == Fraction(purchases, impressions)}")Professional example (R)
# Funnel audit: stage conversion rates and end-to-end product of fractions
impressions <- 25000
clicks <- 5000
page_visits <- 4000
add_to_cart <- 6000
checkouts <- 2400
purchases <- 1800
funnel <- data.frame(
stage = c("impressions → clicks", "clicks → page_visits", "page_visits → add_to_cart",
"add_to_cart → checkouts", "checkouts → purchases"),
n_in = c(impressions, clicks, page_visits, add_to_cart, checkouts),
n_out = c(clicks, page_visits, add_to_cart, checkouts, purchases)
)
funnel$rate <- funnel$n_out / funnel$n_in
funnel$below_20pct <- funnel$rate < 0.20
funnel$cumulative <- cumprod(funnel$rate)
print("Funnel Audit: Stage Conversion Rates (fraction multiplication)")
print(funnel)
end_to_end <- prod(funnel$rate)
cat(sprintf("\nEnd-to-end: %.4f (%.2f%%)\n", end_to_end, 100 * end_to_end))
cat(sprintf("Direct: %d/%d = %.4f Match: %s\n", purchases, impressions, purchases/impressions, abs(prod(funnel$rate) - purchases/impressions) < 1e-9))Source: MRAF