HomeDescriptive StatisticsZ-Score Calculator - Standard Score, P-Value & Percentile

Z-Score Calculator – Standard Score, P-Value & Percentile

Z-Score Calculator - Standard Score, P-Value & Percentile

Z-Score Calculator

Turn any value into a z-score and read off its p-value, percentile and outlier status. Works from raw data or from a mean and standard deviation you already have, handles single values, whole datasets and sample means, and includes a robust modified z-score plus a full z-table.

Standard ScoreP-ValuePercentileOutliersZ-TableMulti-Group

0. Quick Answer

A z-score tells you how many standard deviations a value sits above or below the mean.

Subtract the mean from your value, then divide by the standard deviation. A z of 0 means the value is exactly average. A z of +2 means it is two standard deviations above the mean, which puts it around the 98th percentile. Negative z-scores sit below the mean. Because the result has no units, z-scores let you compare measurements taken on completely different scales, such as a test score against a height.

z = (x − μ) ÷ σ

Rule of thumb: about 68% of values fall within z = ±1, 95% within ±2 and 99.7% within ±3. A |z| above 3 is conventionally treated as an outlier.

Key takeaways

  • z = (x − mean) / SD, the number of standard deviations a value lies from the mean.
  • Z-scores are unit-free, so they let you compare values measured on completely different scales.
  • The empirical rule: roughly 68% of data within ±1, 95% within ±2, 99.7% within ±3 standard deviations.
  • Converting z to a p-value or percentile assumes the data are normally distributed. The z-score itself does not, but every probability read from it does.
  • Using z-scores to find outliers is self-defeating on small samples, because the outlier inflates the very standard deviation used to detect it. Use the modified z-score instead.

📚 1. What Is a Z-Score?

A z-score, also called a standard score, rewrites a measurement in terms of standard deviations from the mean. It answers a question the raw number cannot: is this value ordinary or unusual, given how spread out the data are? A height of 190 cm means nothing on its own. Told that adult male height averages 175 cm with a standard deviation of 7 cm, that becomes a z of +2.14, and now you know it sits above roughly 98% of men.

What this calculator reports:

  • Z-score, the standard score itself, for a single value or for every value in a dataset.
  • P-value, one-tailed and two-tailed, the probability of a value this extreme or more.
  • Percentile rank, the percentage of a normal distribution falling below your value.
  • Modified z-score, built from the median and MAD, which outliers cannot distort.
  • Outlier flags at |z| > 3 and modified |z| > 3.5, the Iglewicz and Hoaglin threshold.
  • Reverse lookup, giving the raw value that corresponds to any z or percentile you name.
  • Z for a sample mean, using the standard error rather than the standard deviation.

A worked one-liner: a student scores 85 on a test where the class averaged 70 with a standard deviation of 10. Their z-score is (85 − 70) ÷ 10 = 1.5, placing them at about the 93rd percentile.

The standard normal curve: where each z-score sits -3-2-1 0+1+2+3 z-score 68% within ±1 95% within ±2 99.7% within ±3 A value beyond ±3 occurs about 3 times in every 1,000 observations
Every z-score maps to a position on this curve. The empirical rule bands show why |z| above 3 is treated as unusual: only about 0.3% of a normal distribution lies out there.

Who uses them: educators convert raw test marks to standard scores so results from different exams can be compared. Clinicians use z-scores for growth charts, bone density (the T-score is a z-score against a young-adult reference) and lab results. Finance uses them in the Altman Z-score for bankruptcy risk. Quality control flags parts beyond ±3 standard deviations. Machine learning standardises features to z-scores so that variables on different scales contribute equally.

Score typeFormulaUse it when
Z-score (population)(x − μ) ÷ σYou know the true population mean and SD
Z-score (sample)(x − x̄) ÷ sYou are working from sample data, the usual case
Z for a sample mean(x̄ − μ) ÷ (σ ÷ √n)Testing whether a sample mean differs from a known value
Modified z-score0.6745(x − Mdn) ÷ MADDetecting outliers, especially in small samples

🧮 2. Set Up Your Calculation

One column is loaded by default. Press Add cluster to compare groups.
Enter a value to score it against the dataset, or leave blank to standardise everything.
📁 Or upload a CSV / Excel file
Supports .csv, .txt, .xlsx and .xls. Every column you click becomes its own cluster.

The classic textbook case. Enter the value you are scoring plus the mean and standard deviation you already know.

Must be greater than zero. A zero SD makes the z-score undefined.

Work backwards: given a z-score or a percentile, what raw value does it correspond to?

For testing whether a sample mean differs from a known population mean. This uses the standard error, not the standard deviation, so the z-score is larger for the same gap.


📊 3. Results

Enter your numbers above and press Calculate Z-Score. The z-score, p-value, percentile, outlier status, charts and reporting sentences will appear here.

🧠 4. Interpretation of Results, In Detail

Run the calculator to fill this section with your own numbers. The ten sub-sections below explain every part of the output.

4.1 Reading the z-score itself

The sign tells you the direction and the magnitude tells you the distance. A z of +1.5 means the value sits one and a half standard deviations above the mean; a z of −0.4 means it sits slightly below. Zero means exactly average. That is the entire interpretation, and it holds regardless of what you measured or what units you used.

The magnitude is what makes z-scores useful. Because the standard deviation sets the scale, a z of 2 means the same thing whether you are measuring reaction times in milliseconds or annual rainfall in millimetres: the value is unusually high for that particular distribution. This is what allows a student to compare their performance on a maths exam against their performance on an essay, even though the two marking schemes share nothing.

4.2 What the percentile actually claims

The percentile converts your z-score into a statement about position: the percentage of the distribution falling below your value. A z of 1.5 corresponds to roughly the 93rd percentile, meaning about 93% of a normal distribution lies below it.

That word normal is doing a great deal of work. The z-score itself is a pure arithmetic operation that requires no assumptions at all. The moment you convert it to a percentile or a p-value, you are assuming the data follow a normal distribution, because you are reading off the normal curve. If your data are skewed, the z-score remains a correct statement about standard deviations, but the percentile attached to it can be badly wrong. For income data, a z of 2 might correspond to the 95th percentile in reality rather than the 97.7th the normal curve predicts.

4.3 The p-value, and choosing a tail

The p-value is the probability of observing a value at least this extreme if the data really are normal with the mean and standard deviation you supplied. A two-tailed p-value counts both extremes: it answers "how likely is a value this far from the mean in either direction". A one-tailed p-value counts only one side.

Choose the tail before you see the data, not after. If your question is genuinely directional, such as "is this batch heavier than specification", a right-tailed test is appropriate. If you simply want to know whether the value is unusual, use two-tailed. Switching to a one-tailed test after seeing which direction the result went halves your p-value without any statistical justification, and it is one of the most common forms of unintentional p-hacking.

4.4 Why z-scores fail at outlier detection on small samples

This is the most important limitation on the page, and most calculators ignore it entirely. The standard advice is to flag any value with |z| > 3. The problem is circular: an extreme value inflates the standard deviation used to compute its own z-score, so it disguises itself.

The mathematics is unforgiving. With n observations, the largest possible z-score is (n − 1) ÷ √n. For n = 10 that ceiling is 2.85, so no value in a sample of ten can ever reach z = 3, however extreme it is. With n = 5 the maximum is 1.79. You could have a value a thousand times larger than the rest and the z-score rule would never flag it. This is why the calculator reports the theoretical maximum alongside your results whenever the sample is small.

4.5 The modified z-score, and when to use it

The fix is to replace the mean with the median and the standard deviation with the median absolute deviation, neither of which an outlier can distort. The modified z-score is 0.6745 times the deviation from the median, divided by the MAD. The constant 0.6745 is the 75th percentile of the standard normal, which rescales the MAD so the modified z is comparable to an ordinary z for normal data.

Iglewicz and Hoaglin recommend flagging values with a modified |z| above 3.5. Because it is built from robust components, it has no artificial ceiling and works on samples where the ordinary z-score is useless. When the two disagree, trust the modified version: a value flagged by the modified z but not by the ordinary z is almost always a genuine outlier that inflated the standard deviation enough to hide itself.

4.6 Sample versus population, and why it matters less than you think

Textbooks write the z-score with the Greek letters μ and σ, implying you know the true population values. In practice you almost never do, so you substitute the sample mean and sample standard deviation. Strictly this produces a slightly different quantity, and with small samples the resulting score follows a t-distribution rather than a normal one.

For most practical purposes the distinction matters less than the normality assumption does. If n is above about 30, the difference between using s and σ is small. If n is below 30 and you are computing a p-value for a sample mean, you should be using a t-test rather than a z-test. The calculator lets you choose the denominator so you can match whatever convention your course or software uses.

4.7 The difference between z for a value and z for a sample mean

These are two different calculations and confusing them is a common error. When you score an individual observation you divide by the standard deviation, because you are asking how unusual that one value is among individuals. When you score a sample mean you divide by the standard error, σ divided by the square root of n, because sample means vary far less than individual values do.

The practical consequence is that the same gap produces a much larger z-score for a mean. A sample mean two units above the population mean might give z = 0.2 as an individual value but z = 1.0 as a mean of 25 observations. Using the standard deviation when you should be using the standard error will make a real effect look unremarkable.

4.8 Reading the four charts

Chart 1 draws the standard normal curve with your z marked and the p-value region shaded, which is the figure most people picture when they think of a z-score. Chart 2 plots every observation as a z-score with reference lines at ±2 and ±3, so outliers are immediately visible. Chart 3 shows the raw distribution so you can judge whether the normality assumption behind the percentile is reasonable. Chart 4 is the cumulative normal curve, which is where the percentile is read from.

Chart 3 deserves particular attention. If the histogram is visibly skewed or has two peaks, the percentile and p-value from charts 1 and 4 are unreliable even though the z-score itself is still arithmetically correct.

4.9 What a z-score cannot tell you

It cannot tell you whether a value is wrong, only whether it is unusual. An extreme z-score might indicate a data-entry error, a faulty instrument, or the single most scientifically interesting observation in your dataset. The statistic cannot distinguish between them and neither should you without going back to the raw record.

It also carries no information about sample size, no measure of its own uncertainty, and no protection against a biased sample. And because it is computed from the mean and standard deviation, it inherits every weakness of those two statistics, including their sensitivity to skew.

4.10 Practical judgement

Compute the z-score, then ask two questions before you use the percentile. First, are the data plausibly normal? Check chart 3, and if the answer is no, report the z-score as a distance in standard deviations but not as a percentile. Second, is the sample large enough for the outlier rule to work? If n is under about 30, use the modified z-score instead. Report the mean, standard deviation and n alongside any z-score, because the same z means completely different things depending on the distribution it came from.

5. How to Write Your Results in Research

▶ Run the analysis above to auto-fill all five examples with your results.

Example 1, APA 7th Edition
The value was ___ standard deviations from the mean (z = ___, p = ___).
📌 Key conventions for this style
  • Italicise z and p. Report p to three decimals, or as p < .001.
  • State whether the p-value is one or two tailed.
  • Give the mean, SD and n that the z-score was computed from.
  • Do not write p = .000; write p < .001.
Example 2, Outlier Screening
Observations were screened for outliers using z-scores. ___
📌 Key conventions for this style
  • State the threshold used and cite a source for it.
  • For small samples, use and report the modified z-score instead, citing Iglewicz and Hoaglin (1993).
  • Say how many values were flagged and whether they were removed or retained.
  • Never remove outliers silently; reviewers will ask.
Example 3, Plain-Language Summary
A value of ___ is well above the typical ___. About ___% of results fall below it.
📌 Key conventions for this style
  • Never write z, sigma or p. Say "standard deviations above average" at most.
  • Percentiles are far more intuitive to a general reader than z-scores.
  • Give units and context for the raw value.
  • Avoid implying a percentile is exact when the data may not be normal.
Example 4, Standardising a Variable
All variables were standardised to z-scores before analysis. ___
📌 Key conventions for this style
  • State whether you standardised using sample or population statistics.
  • In machine learning, fit the scaler on training data only, never on the full dataset.
  • Report the original means and SDs so readers can back-transform.
  • Note that standardising does not make skewed data normal.
Example 5, Z-Test of a Sample Mean
A one-sample z-test compared the sample mean against the known population value. ___
📌 Key conventions for this style
  • A z-test requires a known population standard deviation. If you estimated it, use a t-test instead.
  • Report n, the population mean tested against, and the standard error.
  • State the tail and the alpha level chosen in advance.
  • Give an effect size or confidence interval, not just the p-value.

6. Formulas Used

Z-Score for a Single Value
z = (x − μ) ÷ σ
xThe value you are scoring
μPopulation mean. Use x̄ when working from a sample
σPopulation standard deviation. Use s for a sample
SignPositive means above the mean, negative means below
UndefinedIf σ = 0 every value equals the mean and no z-score exists
Standard Deviation, Sample and Population
s = √[Σ(xᵢ − x̄)² ÷ (n − 1)]  ·  σ = √[Σ(xᵢ − μ)² ÷ n]
n − 1Bessel's correction, used when the data are a sample. Excel STDEV.S, R sd()
nUsed only when you measured the entire population. Excel STDEV.P, NumPy default
EffectThe population version gives a smaller SD and therefore slightly larger z-scores
Percentile and P-Value from Z
percentile = Φ(z) × 100  ·  p₂ₜₐₗ = 2 × [1 − Φ(|z|)]
Φ(z)The standard normal cumulative distribution function, the area to the left of z
Right tailp = 1 − Φ(z)
Left tailp = Φ(z)
AssumptionThese require the data to be normally distributed. The z-score alone does not
Reverse: Value from Z or Percentile
x = μ + zσ  ·  z = Φ⁻¹(p)
x = μ + zσRearranging the z formula recovers the raw value
Φ⁻¹The inverse normal, sometimes called the probit or quantile function
ExampleThe 95th percentile is z = 1.6449, so x = μ + 1.6449σ
Z for a Sample Mean
z = (x̄ − μ) ÷ (σ ÷ √n)
The sample mean being tested
σ ÷ √nThe standard error, not the standard deviation
WhySample means vary far less than individual values, so the denominator must be smaller
CautionIf σ is estimated from the sample and n is small, use a t-test instead
Modified Z-Score, Robust to Outliers
Mᵢ = 0.6745 × (xᵢ − Mdn) ÷ MAD
MdnThe median, which an outlier cannot move
MADMedian absolute deviation, median of |x − Mdn|
0.6745The 75th percentile of the standard normal, rescaling MAD to match an ordinary SD
ThresholdFlag |M| > 3.5 as an outlier (Iglewicz and Hoaglin, 1993)
Use whenn is small, or you suspect the SD has already been inflated
The Ceiling on Z-Scores in Small Samples
|z|ₘₐₓ = (n − 1) ÷ √n
n = 5Maximum possible |z| is 1.79, so nothing can ever reach 3
n = 10Maximum is 2.85, still below the usual outlier threshold
n = 30Maximum is 5.29, so the rule finally becomes usable
ConsequenceThe |z| > 3 outlier rule is worthless below about n = 11. Use the modified z-score

📝 7. How to Use This Calculator

  1. Paste your numbers into the data column. Raw data mode opens first because it is what most people need. Enter your values comma-separated, exactly as the placeholder shows. The calculator works out the mean and standard deviation for you, then scores every observation. Leave the highlight box blank to standardise the whole dataset, or type a value to score just that one.
  2. Or switch mode if you already have the summary statistics. I know the mean and SD is the classic textbook case where you enter the value, the mean and the standard deviation directly. Reverse works backwards from a z-score or percentile to a raw value. Z for a sample mean uses the standard error instead of the standard deviation. In every mode the standard deviation must be greater than zero, because dividing by zero leaves the z-score undefined.
  3. Load a sample dataset to see how it behaves. Eight are built in, including a heart-rate set containing a genuine outlier and a ten-value set that demonstrates the small-sample ceiling. Selecting one replaces the data column immediately.
  4. Add clusters to compare groups. Each gets its own mean, standard deviation and set of z-scores. Every column has its own Clear and Remove button, and Remove is disabled on the last remaining column.
  5. Or upload a CSV. Open the upload panel inside the raw data tab and click the column names you want. Every column you click becomes its own cluster.
  6. Choose your standard deviation type. Sample (n − 1) is correct unless you genuinely measured the whole population. This is the setting that makes Excel's STDEV.S and STDEV.P disagree.
  7. Choose the p-value tail before you look at the result. Two-tailed asks whether the value is unusual in either direction; one-tailed commits to a direction. Deciding after seeing the data halves your p-value without justification.
  8. Press Calculate Z-Score. Nothing is computed until you do, and changing any input clears the results so you never read stale numbers.
  9. Read the colour bar and the warnings first. The bar shows instantly where your z sits against the empirical rule bands, and the warnings will tell you if your sample is too small for the |z| > 3 rule to be capable of firing at all.
  10. Check chart 3 before trusting the percentile. The z-score is always arithmetically correct, but the percentile and p-value assume normality. If the histogram is visibly skewed, report the z-score as a distance and drop the percentile.

📊 8. How to Calculate a Z-Score in Excel

Excel can do every part of this: the mean, the standard deviation, the z-score itself, the percentile, the p-value, and the reverse lookup. There are two ways to write the z-score and three functions you need for the normal curve. Below is the whole workflow in ten steps, each with a picture of what your sheet should look like.

The five functions that matter. AVERAGE, STDEV.S or STDEV.P, STANDARDIZE, NORM.S.DIST and NORM.S.INV. Everything else on this page is built from those five.
Xz-scores.xlsx - ExcelA1fxValueABCD1ValueStatisticResult252Mean348SD (sample)455SD (population)561n647758

Step 1. Put your data in one column with a header in A1, and set aside a small block for the summary statistics.

Xz-scores.xlsx - ExcelD2fx=AVERAGE(A2:A13)ABCD1ValueStatisticResult252Mean53.1667348SD (sample)455SD (population)561n647758

Step 2. AVERAGE gives the mean, 53.1667. Select the whole data range, not just the rows you can see.

Xz-scores.xlsx - ExcelD3fx=STDEV.S(A2:A13)ABCD1ValueStatisticResult252Mean53.1667348SD (sample)5.6702455SD (population)5.4288561n12647758

Step 3. STDEV.S uses n minus 1 and is the right choice for a sample. STDEV.P uses n and gives the smaller 5.4288. Pick one and stay with it.

Xz-scores.xlsx - ExcelB2fx=(A2-$E$2)/$E$3ABCDE1ValueZ-Score252-0.2058Mean53.1667348SD5.6702455561647758

Step 4. The manual formula. The dollar signs lock the mean and SD cells so you can drag the formula down the whole column without the references sliding.

Xz-scores.xlsx - ExcelB3fx=STANDARDIZE(A3,$E$2,$E$3)ABCDE1ValueZ-Score252-0.2058Mean53.1667348-0.9112SD5.6702455561647758

Step 5. STANDARDIZE(x, mean, sd) does exactly the same thing and is easier to read. Both give -0.9112 for the value 48.

Xz-scores.xlsx - ExcelB3fx=NORM.S.DIST(B2,TRUE)AB1QuantityResult2Z-score1.38153Percentile0.91644p two tailed5p right tail6

Step 6. NORM.S.DIST with TRUE returns the cumulative area, 0.9164, so the value sits at about the 92nd percentile. The FALSE argument returns the curve height instead, which is not what you want.

Xz-scores.xlsx - ExcelB4fx=2*(1-NORM.S.DIST(ABS(B2),TRUE))AB1QuantityResult2Z-score1.38153Percentile0.91644p two tailed0.16715p right tail0.08366

Step 7. The two-tailed p-value is 0.1671. The right-tail version drops the 2 and gives 0.0836. Decide which you need before you look at the number.

Xz-scores.xlsx - ExcelB3fx=NORM.S.INV(B2)AB1InputResult2Percentile wanted0.953Z for that percentile1.64494Raw value62.49385

Step 8. Working backwards. NORM.S.INV turns a percentile into a z-score, then mean plus z times SD recovers the raw value, 62.4938.

Xz-scores.xlsx - ExcelC2fx=IF(ABS(B2)>3,"Outlier","OK")ABC1ValueZFlag252-0.2058OK348-0.91124631.7342545-1.4403

Step 9. A flag column. Note that with n = 12 the largest possible z-score is only 3.18, so this rule can barely fire at all. Below n = 11 it can never fire.

Xz-scores.xlsx - ExcelC2fx=0.6745*(A2-$F$2)/$F$3ABCDEF1Value|x-Mdn|Modified Z2521.0-0.1928Median53.03MAD3.545

Step 10. The robust alternative. Median with =MEDIAN(A2:A13), MAD with =MEDIAN(ABS(A2:A13-MEDIAN(A2:A13))) entered as an array formula, then flag anything above 3.5 in absolute value.

The formula cheat sheet

What you wantExcel formulaNotes
Mean=AVERAGE(A2:A13)Ignores blanks and text
Sample SD=STDEV.S(A2:A13)Divides by n minus 1. The usual choice
Population SD=STDEV.P(A2:A13)Divides by n. Only if you measured everyone
Z-score, manual=(A2-$E$2)/$E$3Dollar signs lock the mean and SD cells
Z-score, built in=STANDARDIZE(A2,$E$2,$E$3)Identical result, clearer to read
Percentile from z=NORM.S.DIST(B2,TRUE)TRUE gives cumulative area. Multiply by 100 for a percentage
Two-tailed p=2*(1-NORM.S.DIST(ABS(B2),TRUE))ABS handles negative z-scores
Right-tail p=1-NORM.S.DIST(B2,TRUE)Only if the direction was decided in advance
Left-tail p=NORM.S.DIST(B2,TRUE)Same as the percentile
Z from percentile=NORM.S.INV(0.95)Returns 1.6449
Value from z=$E$2+B2*$E$3Rearranged z formula
Z for a sample mean=(xbar-mu)/(sd/SQRT(n))Standard error in the denominator, not SD
Median=MEDIAN(A2:A13)For the modified z-score
MAD=MEDIAN(ABS(A2:A13-MEDIAN(A2:A13)))Array formula. Ctrl+Shift+Enter in older Excel
Outlier flag=IF(ABS(B2)>3,"Outlier","OK")Use 3.5 with the modified z-score

Five mistakes that catch people out

  • Forgetting the dollar signs. Drag =(A2-E2)/E3 down and row 3 will divide by the wrong cells. Write $E$2 and $E$3.
  • Using NORM.DIST instead of NORM.S.DIST. The S version is the standard normal and takes a z-score. The plain version needs the mean and SD as extra arguments.
  • Passing FALSE to NORM.S.DIST. That returns the height of the curve, not the area, and the number will look plausible but be meaningless as a percentile.
  • Mixing STDEV.S and STDEV.P across a workbook. The z-scores will not be comparable. Decide once.
  • Applying the |z| > 3 rule to a short column. With 12 rows the largest attainable z is 3.18. With 8 rows it is 2.47. The rule silently never fires.
Google Sheets. Every formula above works unchanged, except that Sheets also accepts the older NORMSDIST and NORMSINV names. The MAD array formula needs ARRAYFORMULA(...) wrapped around it.

📈 9. How to Calculate a Z-Score in R

Base R does all of this with no packages at all. scale() standardises a vector, pnorm() converts a z-score to a cumulative probability, and qnorm() goes the other way. The script below computes every quantity on this page and draws one figure. Copy it whole and it will run.

The one trap in R. sd() always uses n minus 1. There is no population option, so if you need the population SD you must write sd(x) * sqrt((n - 1) / n) yourself. NumPy has the opposite default, which is why R and Python can disagree on the same data.
R, base packages only
# Z-Score Calculator in R (base R, no packages)

# ---- 1. Your data -----------------------------------------------------
x         <- c(52, 48, 55, 61, 47, 58, 50, 63, 45, 56, 54, 49)
highlight <- 61            # the value you want to score

# ---- 2. Mean and standard deviation -----------------------------------
n    <- length(x)
mean_x <- mean(x)
sd_x   <- sd(x)            # sample SD, divides by n - 1
# population SD if you need it:
# sd_pop <- sd(x) * sqrt((n - 1) / n)

z <- (x - mean_x) / sd_x   # or simply: z <- as.vector(scale(x))

# ---- 3. Percentile and p-value ----------------------------------------
z_hi  <- (highlight - mean_x) / sd_x
pct   <- pnorm(z_hi) * 100
p_two <- 2 * (1 - pnorm(abs(z_hi)))
p_rt  <- 1 - pnorm(z_hi)   # right tail only

# ---- 4. Robust modified z-score (Iglewicz & Hoaglin 1993) -------------
med   <- median(x)
mad_x <- median(abs(x - med))          # raw MAD, not R's mad() which rescales
mod_z <- if (mad_x > 0) 0.6745 * (x - med) / mad_x else rep(0, n)

z_ceiling <- (n - 1) / sqrt(n)         # largest |z| any value can reach

cat(sprintf("n = %d   mean = %.4f   SD = %.4f\n", n, mean_x, sd_x))
cat(sprintf("z for %g = %.4f\n", highlight, z_hi))
cat(sprintf("percentile = %.2f%%   two-tailed p = %.4f\n", pct, p_two))
cat(sprintf("max possible |z| at n=%d is %.2f\n", n, z_ceiling))
cat("outliers |z|>3       :", x[abs(z) > 3], "\n")
cat("outliers |mod z|>3.5 :", x[abs(mod_z) > 3.5], "\n")

# ---- 5. One figure ----------------------------------------------------
grid <- seq(-4, 4, length.out = 600)
plot(grid, dnorm(grid), type = "l", lwd = 2, col = "#0f766e",
     xlab = "z-score (standard deviations from the mean)",
     ylab = "density", bty = "n",
     main = sprintf("Z-Score Summary   n=%d, mean=%.2f, SD=%.2f",
                    n, mean_x, sd_x))

# shade the two tails beyond |z_hi|
tail_r <- grid[grid >=  abs(z_hi)]
tail_l <- grid[grid <= -abs(z_hi)]
polygon(c(tail_r, rev(tail_r)), c(dnorm(tail_r), rep(0, length(tail_r))),
        col = adjustcolor("#f59e0b", 0.45), border = NA)
polygon(c(tail_l, rev(tail_l)), c(dnorm(tail_l), rep(0, length(tail_l))),
        col = adjustcolor("#f59e0b", 0.45), border = NA)

abline(v = z_hi, col = "#7c3aed", lwd = 2.2)
abline(v = c(-3, -2, 2, 3), col = "#94a3b8", lty = 3)
points(z, rep(-0.012, n), pch = 19, col = "#0ea5e9", xpd = NA)

legend("topright", bty = "n", cex = 0.85,
       legend = c(sprintf("z = %.3f  (%.1fth pct)", z_hi, pct),
                  sprintf("two-tailed p = %.4f", p_two),
                  "your data as z-scores"),
       col = c("#7c3aed", "#f59e0b", "#0ea5e9"),
       lwd = c(2.2, 6, NA), pch = c(NA, NA, 19))

What the script prints

LineOutputMeaning
1n = 12 mean = 53.1667 SD = 5.6702The summary statistics the z-scores are built from. Always report these
2z for 61 = 1.3815The value 61 sits 1.38 sample standard deviations above the mean
3percentile = 91.64% two-tailed p = 0.1671About 92% of a normal distribution lies below it, and a value this far from the mean in either direction is not unusual
4max possible |z| at n=12 is 3.18The ceiling. With only twelve observations the |z| > 3 rule barely has room to fire
5 and 6Two empty outlier listsNeither the ordinary nor the modified rule flags anything, which agrees with the figure

Line-by-line explanation

  • Block 1 holds the only two things you change: your vector and the value you want to score. Everything below is generic.
  • Block 2 computes the mean and the sample standard deviation. The commented line shows the population conversion, because R will not do it for you. scale(x) is the idiomatic shortcut but returns a matrix, so as.vector() is needed if you want a plain numeric vector back.
  • Block 3 converts the highlighted z to a percentile with pnorm() and to p-values. Note that pnorm() is the direct equivalent of Excel's NORM.S.DIST(z, TRUE), and qnorm() is NORM.S.INV.
  • Block 4 builds the robust version. Be careful here: R's built-in mad() already multiplies by 1.4826, so feeding it into the 0.6745 formula would double-scale the result. The script computes the raw median absolute deviation directly to avoid that.
  • Block 5 draws a single figure containing everything: the standard normal curve, the shaded p-value region, a vertical line at your z, dotted guides at ±2 and ±3, and every observation plotted along the bottom as a z-score. xpd = NA lets those points sit below the axis without being clipped.

Useful one-liners

TaskR
Standardise a vectoras.vector(scale(x))
Standardise every numeric column of a data frameas.data.frame(scale(df))
Percentile from zpnorm(z)
Z from percentileqnorm(0.95) gives 1.644854
Two-tailed p2 * pnorm(-abs(z))
Raw value from zmean_x + z * sd_x
Test normality firstshapiro.test(x)
Q-Q plotqqnorm(x); qqline(x)

🐍 10. How to Calculate a Z-Score in Python

NumPy computes the z-scores, SciPy supplies the normal distribution, and Matplotlib draws the figure. The script below was run before being published, so the printed output shown underneath is real, not typed by hand.

The one trap in Python. np.std() defaults to ddof=0, the population version. R's sd() defaults to n minus 1. If your R and Python answers differ slightly, this is almost always why. Write ddof=1 explicitly whenever your data are a sample. Note that scipy.stats.zscore() also defaults to ddof=0.
Python 3, NumPy + SciPy + Matplotlib
# Z-Score Calculator in Python
# Computes z-scores, percentiles and p-values, and draws one summary figure.
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# ---- 1. Your data -----------------------------------------------------
x = np.array([52, 48, 55, 61, 47, 58, 50, 63, 45, 56, 54, 49], dtype=float)
highlight = 61.0          # the value you want to score

# ---- 2. Mean and standard deviation -----------------------------------
n    = x.size
mean = x.mean()
sd   = x.std(ddof=1)      # ddof=1 = sample SD. Use ddof=0 for population
z    = (x - mean) / sd

# ---- 3. Percentile and p-value for the highlighted value --------------
z_hi  = (highlight - mean) / sd
pct   = stats.norm.cdf(z_hi) * 100
p_two = 2 * (1 - stats.norm.cdf(abs(z_hi)))

# ---- 4. Robust modified z-score (Iglewicz and Hoaglin 1993) -----------
med   = np.median(x)
mad   = np.median(np.abs(x - med))
mod_z = 0.6745 * (x - med) / mad if mad > 0 else np.zeros_like(x)

z_ceiling = (n - 1) / np.sqrt(n)   # largest |z| any value can reach

print(f"n = {n}   mean = {mean:.4f}   SD = {sd:.4f}")
print(f"z for {highlight:g} = {z_hi:.4f}")
print(f"percentile = {pct:.2f}%   two-tailed p = {p_two:.4f}")
print(f"max possible |z| at n={n} is {z_ceiling:.2f}")
print("outliers |z|>3      :", x[np.abs(z) > 3].tolist())
print("outliers |mod z|>3.5:", x[np.abs(mod_z) > 3.5].tolist())

# ---- 5. One figure ----------------------------------------------------
fig, ax = plt.subplots(figsize=(9, 5))
grid = np.linspace(-4, 4, 600)
ax.plot(grid, stats.norm.pdf(grid), color="#0f766e", lw=2)
ax.fill_between(grid, stats.norm.pdf(grid), where=np.abs(grid) >= abs(z_hi),
                color="#f59e0b", alpha=.45,
                label=f"two-tailed p = {p_two:.4f}")
ax.axvline(z_hi, color="#7c3aed", lw=2.2,
           label=f"z = {z_hi:.3f}  ({pct:.1f}th pct)")
ax.scatter(z, np.full_like(z, -0.012), s=46, color="#0ea5e9",
           zorder=3, clip_on=False, label="your data as z-scores")
for b in (-3, -2, 2, 3):
    ax.axvline(b, color="#94a3b8", ls=":", lw=1)
ax.set_xlabel("z-score (standard deviations from the mean)")
ax.set_ylabel("density")
ax.set_title(f"Z-Score Summary   n={n}, mean={mean:.2f}, SD={sd:.2f}")
ax.legend(frameon=False, fontsize=9)
ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
fig.savefig("z_score_summary.png", dpi=150)
plt.show()

Actual output from running the script

n = 12   mean = 53.1667   SD = 5.6702
z for 61 = 1.3815
percentile = 91.64%   two-tailed p = 0.1671
max possible |z| at n=12 is 3.18
outliers |z|>3      : []
outliers |mod z|>3.5: []

These are the same numbers the R script produces and the same numbers the calculator at the top of this page produces, which is a useful sanity check whenever you port an analysis between tools.

Line-by-line explanation

  • Block 1 is the only part you edit. Setting dtype=float avoids integer division surprises if you later divide the array.
  • Block 2 computes the mean and the sample standard deviation, then vectorises the z-score across the whole array in one line. NumPy broadcasting means no loop is needed.
  • Block 3 uses stats.norm.cdf, the direct equivalent of R's pnorm() and Excel's NORM.S.DIST(z, TRUE). For the reverse direction use stats.norm.ppf(0.95), which returns 1.6449.
  • Block 4 builds the robust modified z-score. The guard on mad > 0 matters: if more than half your values are identical the MAD is zero and the formula would divide by zero.
  • Block 5 draws the single summary figure. fill_between with a where mask shades both tails in one call, clip_on=False lets the data points sit just below the axis, and hiding the top and right spines keeps the plot publication-ready.

Useful one-liners

TaskPython
Z-scores, sample SDstats.zscore(x, ddof=1)
Z-scores, population SDstats.zscore(x)
Standardise a DataFrame(df - df.mean()) / df.std() (pandas uses ddof=1)
Scikit-learn scalerStandardScaler().fit_transform(X) (uses ddof=0)
Percentile from zstats.norm.cdf(z)
Z from percentilestats.norm.ppf(0.95)
Two-tailed p2 * stats.norm.sf(abs(z))
Raw value from zmean + z * sd
Test normality firststats.shapiro(x)
Q-Q plotstats.probplot(x, plot=plt)
Machine learning warning. When standardising features for a model, fit the scaler on the training set only and apply that same mean and SD to the test set. Fitting on the full dataset leaks information from the test set into training and inflates your accuracy.

📋 11. Reference Tables

11.1 Standard normal table, negative z-scores

Find your z-score to one decimal place down the left column, then read across to the second decimal place. The number in the cell is the area to the left of that z, which is the percentile expressed as a proportion.

z0.000.010.020.030.040.050.060.070.080.09
-0.00.50000.49600.49200.48800.48400.48010.47610.47210.46810.4641
-0.10.46020.45620.45220.44830.44430.44040.43640.43250.42860.4247
-0.20.42070.41680.41290.40900.40520.40130.39740.39360.38970.3859
-0.30.38210.37830.37450.37070.36690.36320.35940.35570.35200.3483
-0.40.34460.34090.33720.33360.33000.32640.32280.31920.31560.3121
-0.50.30850.30500.30150.29810.29460.29120.28770.28430.28100.2776
-0.60.27430.27090.26760.26430.26110.25780.25460.25140.24830.2451
-0.70.24200.23890.23580.23270.22960.22660.22360.22060.21770.2148
-0.80.21190.20900.20610.20330.20050.19770.19490.19220.18940.1867
-0.90.18410.18140.17880.17620.17360.17110.16850.16600.16350.1611
-1.00.15870.15620.15390.15150.14920.14690.14460.14230.14010.1379
-1.10.13570.13350.13140.12920.12710.12510.12300.12100.11900.1170
-1.20.11510.11310.11120.10930.10750.10560.10380.10200.10030.0985
-1.30.09680.09510.09340.09180.09010.08850.08690.08530.08380.0823
-1.40.08080.07930.07780.07640.07490.07350.07210.07080.06940.0681
-1.50.06680.06550.06430.06300.06180.06060.05940.05820.05710.0559
-1.60.05480.05370.05260.05160.05050.04950.04850.04750.04650.0455
-1.70.04460.04360.04270.04180.04090.04010.03920.03840.03750.0367
-1.80.03590.03510.03440.03360.03290.03220.03140.03070.03010.0294
-1.90.02870.02810.02740.02680.02620.02560.02500.02440.02390.0233
-2.00.02280.02220.02170.02120.02070.02020.01970.01920.01880.0183
-2.10.01790.01740.01700.01660.01620.01580.01540.01500.01460.0143
-2.20.01390.01360.01320.01290.01250.01220.01190.01160.01130.0110
-2.30.01070.01040.01020.00990.00960.00940.00910.00890.00870.0084
-2.40.00820.00800.00780.00750.00730.00710.00690.00680.00660.0064
-2.50.00620.00600.00590.00570.00550.00540.00520.00510.00490.0048
-2.60.00470.00450.00440.00430.00410.00400.00390.00380.00370.0036
-2.70.00350.00340.00330.00320.00310.00300.00290.00280.00270.0026
-2.80.00260.00250.00240.00230.00230.00220.00210.00210.00200.0019
-2.90.00190.00180.00180.00170.00160.00160.00150.00150.00140.0014
-3.00.00130.00130.00130.00120.00120.00110.00110.00110.00100.0010
-3.10.00100.00090.00090.00090.00080.00080.00080.00080.00070.0007
-3.20.00070.00070.00060.00060.00060.00060.00060.00050.00050.0005
-3.30.00050.00050.00050.00040.00040.00040.00040.00040.00040.0003
-3.40.00030.00030.00030.00030.00030.00030.00030.00030.00030.0002

11.2 Standard normal table, positive z-scores

Same reading method. For example z = 1.38 gives 0.9162, so about 91.6% of the distribution lies below that value.

z0.000.010.020.030.040.050.060.070.080.09
0.00.50000.50400.50800.51200.51600.51990.52390.52790.53190.5359
0.10.53980.54380.54780.55170.55570.55960.56360.56750.57140.5753
0.20.57930.58320.58710.59100.59480.59870.60260.60640.61030.6141
0.30.61790.62170.62550.62930.63310.63680.64060.64430.64800.6517
0.40.65540.65910.66280.66640.67000.67360.67720.68080.68440.6879
0.50.69150.69500.69850.70190.70540.70880.71230.71570.71900.7224
0.60.72570.72910.73240.73570.73890.74220.74540.74860.75170.7549
0.70.75800.76110.76420.76730.77040.77340.77640.77940.78230.7852
0.80.78810.79100.79390.79670.79950.80230.80510.80780.81060.8133
0.90.81590.81860.82120.82380.82640.82890.83150.83400.83650.8389
1.00.84130.84380.84610.84850.85080.85310.85540.85770.85990.8621
1.10.86430.86650.86860.87080.87290.87490.87700.87900.88100.8830
1.20.88490.88690.88880.89070.89250.89440.89620.89800.89970.9015
1.30.90320.90490.90660.90820.90990.91150.91310.91470.91620.9177
1.40.91920.92070.92220.92360.92510.92650.92790.92920.93060.9319
1.50.93320.93450.93570.93700.93820.93940.94060.94180.94290.9441
1.60.94520.94630.94740.94840.94950.95050.95150.95250.95350.9545
1.70.95540.95640.95730.95820.95910.95990.96080.96160.96250.9633
1.80.96410.96490.96560.96640.96710.96780.96860.96930.96990.9706
1.90.97130.97190.97260.97320.97380.97440.97500.97560.97610.9767
2.00.97720.97780.97830.97880.97930.97980.98030.98080.98120.9817
2.10.98210.98260.98300.98340.98380.98420.98460.98500.98540.9857
2.20.98610.98640.98680.98710.98750.98780.98810.98840.98870.9890
2.30.98930.98960.98980.99010.99040.99060.99090.99110.99130.9916
2.40.99180.99200.99220.99250.99270.99290.99310.99320.99340.9936
2.50.99380.99400.99410.99430.99450.99460.99480.99490.99510.9952
2.60.99530.99550.99560.99570.99590.99600.99610.99620.99630.9964
2.70.99650.99660.99670.99680.99690.99700.99710.99720.99730.9974
2.80.99740.99750.99760.99770.99770.99780.99790.99790.99800.9981
2.90.99810.99820.99820.99830.99840.99840.99850.99850.99860.9986
3.00.99870.99870.99870.99880.99880.99890.99890.99890.99900.9990
3.10.99900.99910.99910.99910.99920.99920.99920.99920.99930.9993
3.20.99930.99930.99940.99940.99940.99940.99940.99950.99950.9995
3.30.99950.99950.99950.99960.99960.99960.99960.99960.99960.9997
3.40.99970.99970.99970.99970.99970.99970.99970.99970.99970.9998
How to use the table backwards. To find the z-score for a given percentile, hunt inside the table for the closest probability and read off the row and column. For 0.9500 the closest cell is 0.9495 at z = 1.64, which is why textbooks give 1.645 as the interpolated value.

11.3 The empirical rule

Within z ofArea insideArea in the tails
±168.27%31.73%
±1.64590.00%10.00%
±1.9695.00%5.00%
±295.45%4.55%
±2.57699.00%1.00%
±399.73%0.27%

11.4 Common critical values

ConfidenceAlphaTwo-tailed critical zOne-tailed critical z
80%0.21.28160.8416
90%0.11.64491.2816
95%0.051.961.6449
98%0.022.32632.0537
99%0.012.57582.3263
99.9%0.0013.29053.0902

11.5 The maximum possible z-score by sample size

This is the table nobody prints, and it is the reason the |z| > 3 outlier rule fails so often. The largest z-score attainable in a sample of n is (n − 1) divided by the square root of n, no matter how extreme the value is.

nMaximum possible |z|Can |z| > 3 ever fire?
41.50No
51.79No
62.04No
82.47No
102.85No
113.02Yes
123.18Yes
153.61Yes
204.25Yes
254.80Yes
305.29Yes
506.93Yes
1009.90Yes

Below n = 11 the ordinary z-score rule is mathematically incapable of flagging anything. Use the modified z-score with a threshold of 3.5 instead.

11.6 Z-scores, percentiles and everyday equivalents

Z-scorePercentileIQ (mean 100, SD 15)Interpretation
-3.00.1355Extremely low
-2.02.2870Well below average
-1.015.8785Below average
-0.530.8592.5Slightly below average
0.050.00100Exactly average
+0.569.15107.5Slightly above average
+1.084.13115Above average
+1.64595.00124.7Top 5%
+1.9697.50129.4Top 2.5%
+2.097.72130Well above average
+2.57699.50138.6Top 0.5%
+3.099.87145Extremely high

11.7 Z-score to p-value quick reference

|z|Two-tailed pOne-tailed pSignificant at 0.05?
0.500.61710.3085No
1.000.31730.1587No
1.500.13360.0668No
1.6450.10000.0500One-tailed only
1.960.05000.0250Yes, exactly at the boundary
2.000.04550.0228Yes
2.5760.01000.0050Yes
3.000.00270.0013Yes
3.290.00100.0005Yes

11.8 Area between the mean and z

Some textbooks print the table this way instead. Each cell gives the area between 0 and z, which is simply the cumulative area minus 0.5. If your course uses this style, the value for z = 1.96 is 0.4750 rather than 0.9750.

z0.000.010.020.030.040.050.060.070.080.09
0.00.00000.00400.00800.01200.01600.01990.02390.02790.03190.0359
0.10.03980.04380.04780.05170.05570.05960.06360.06750.07140.0753
0.20.07930.08320.08710.09100.09480.09870.10260.10640.11030.1141
0.30.11790.12170.12550.12930.13310.13680.14060.14430.14800.1517
0.40.15540.15910.16280.16640.17000.17360.17720.18080.18440.1879
0.50.19150.19500.19850.20190.20540.20880.21230.21570.21900.2224
0.60.22570.22910.23240.23570.23890.24220.24540.24860.25170.2549
0.70.25800.26110.26420.26730.27040.27340.27640.27940.28230.2852
0.80.28810.29100.29390.29670.29950.30230.30510.30780.31060.3133
0.90.31590.31860.32120.32380.32640.32890.33150.33400.33650.3389
1.00.34130.34380.34610.34850.35080.35310.35540.35770.35990.3621
1.10.36430.36650.36860.37080.37290.37490.37700.37900.38100.3830
1.20.38490.38690.38880.39070.39250.39440.39620.39800.39970.4015
1.30.40320.40490.40660.40820.40990.41150.41310.41470.41620.4177
1.40.41920.42070.42220.42360.42510.42650.42790.42920.43060.4319
1.50.43320.43450.43570.43700.43820.43940.44060.44180.44290.4441
1.60.44520.44630.44740.44840.44950.45050.45150.45250.45350.4545
1.70.45540.45640.45730.45820.45910.45990.46080.46160.46250.4633
1.80.46410.46490.46560.46640.46710.46780.46860.46930.46990.4706
1.90.47130.47190.47260.47320.47380.47440.47500.47560.47610.4767
2.00.47720.47780.47830.47880.47930.47980.48030.48080.48120.4817
2.10.48210.48260.48300.48340.48380.48420.48460.48500.48540.4857
2.20.48610.48640.48680.48710.48750.48780.48810.48840.48870.4890
2.30.48930.48960.48980.49010.49040.49060.49090.49110.49130.4916
2.40.49180.49200.49220.49250.49270.49290.49310.49320.49340.4936
2.50.49380.49400.49410.49430.49450.49460.49480.49490.49510.4952
2.60.49530.49550.49560.49570.49590.49600.49610.49620.49630.4964
2.70.49650.49660.49670.49680.49690.49700.49710.49720.49730.4974
2.80.49740.49750.49760.49770.49770.49780.49790.49790.49800.4981
2.90.49810.49820.49820.49830.49840.49840.49850.49850.49860.4986
3.00.49870.49870.49870.49880.49880.49890.49890.49890.49900.4990

11.9 Right-tail areas, the one-tailed p-value table

Each cell is the area to the right of z, which is exactly the one-tailed p-value. Double it for a two-tailed test. This is the table to use when you are testing a directional hypothesis.

z0.000.010.020.030.040.050.060.070.080.09
0.00.50000.49600.49200.48800.48400.48010.47610.47210.46810.4641
0.10.46020.45620.45220.44830.44430.44040.43640.43250.42860.4247
0.20.42070.41680.41290.40900.40520.40130.39740.39360.38970.3859
0.30.38210.37830.37450.37070.36690.36320.35940.35570.35200.3483
0.40.34460.34090.33720.33360.33000.32640.32280.31920.31560.3121
0.50.30850.30500.30150.29810.29460.29120.28770.28430.28100.2776
0.60.27430.27090.26760.26430.26110.25780.25460.25140.24830.2451
0.70.24200.23890.23580.23270.22960.22660.22360.22060.21770.2148
0.80.21190.20900.20610.20330.20050.19770.19490.19220.18940.1867
0.90.18410.18140.17880.17620.17360.17110.16850.16600.16350.1611
1.00.15870.15620.15390.15150.14920.14690.14460.14230.14010.1379
1.10.13570.13350.13140.12920.12710.12510.12300.12100.11900.1170
1.20.11510.11310.11120.10930.10750.10560.10380.10200.10030.0985
1.30.09680.09510.09340.09180.09010.08850.08690.08530.08380.0823
1.40.08080.07930.07780.07640.07490.07350.07210.07080.06940.0681
1.50.06680.06550.06430.06300.06180.06060.05940.05820.05710.0559
1.60.05480.05370.05260.05160.05050.04950.04850.04750.04650.0455
1.70.04460.04360.04270.04180.04090.04010.03920.03840.03750.0367
1.80.03590.03510.03440.03360.03290.03220.03140.03070.03010.0294
1.90.02870.02810.02740.02680.02620.02560.02500.02440.02390.0233
2.00.02280.02220.02170.02120.02070.02020.01970.01920.01880.0183
2.10.01790.01740.01700.01660.01620.01580.01540.01500.01460.0143
2.20.01390.01360.01320.01290.01250.01220.01190.01160.01130.0110
2.30.01070.01040.01020.00990.00960.00940.00910.00890.00870.0084
2.40.00820.00800.00780.00750.00730.00710.00690.00680.00660.0064
2.50.00620.00600.00590.00570.00550.00540.00520.00510.00490.0048
2.60.00470.00450.00440.00430.00410.00400.00390.00380.00370.0036
2.70.00350.00340.00330.00320.00310.00300.00290.00280.00270.0026
2.80.00260.00250.00240.00230.00230.00220.00210.00210.00200.0019
2.90.00190.00180.00180.00170.00160.00160.00150.00150.00140.0014
3.00.00130.00130.00130.00120.00120.00110.00110.00110.00100.0010

11.10 Z-scores converted to other standardised scales

Almost every named score system is a z-score in disguise, rescaled to avoid decimals and negative numbers. This table shows the conversions, so you can move between them without recomputing anything.

Z-scorePercentileT-score
M 50, SD 10
IQ
M 100, SD 15
SAT section
M 500, SD 100
GRE section
M 150, SD 8.75
StanineSten
-3.00.132055.0200123.811
-2.50.622562.5250128.111
-2.02.283070.0300132.512
-1.56.683577.5350136.922
-1.015.874085.0400141.234
-0.530.854592.5450145.644
0.050.0050100.0500150.056
+0.569.1555107.5550154.466
+1.084.1360115.0600158.878
+1.593.3265122.5650163.188
+2.097.7270130.0700167.5910
+2.599.3875137.5750171.9910
+3.099.8780145.0800176.2910

Conversion formulas: T = 50 + 10z, IQ = 100 + 15z, SAT section = 500 + 100z, GRE section = 150 + 8.75z, stanine = 5 + 2z rounded and clipped to 1-9, sten = 5.5 + 2z rounded and clipped to 1-10.

11.11 How rare is that z-score?

Percentages are hard to feel. This table restates the same probabilities as "one in how many", which is usually more intuitive when you are deciding whether an observation is worth investigating.

|z|Rarity, one sideRarity, both sidesOne-tailed pTwo-tailed p
11 in 61 in 31.587e-013.173e-01
1.51 in 151 in 76.681e-021.336e-01
1.961 in 401 in 202.500e-025.000e-02
21 in 441 in 222.275e-024.550e-02
2.51 in 1611 in 816.210e-031.242e-02
2.5761 in 2001 in 1004.998e-039.995e-03
31 in 7411 in 3701.350e-032.700e-03
3.291 in 1,9961 in 9985.009e-041.002e-03
3.51 in 4,2991 in 2,1492.326e-044.653e-04
41 in 31,5741 in 15,7873.167e-056.334e-05
4.51 in 294,3191 in 147,1603.398e-066.795e-06
51 in 3,488,5561 in 1,744,2782.867e-075.733e-07
61 in 1,013,594,6351 in 506,797,3179.866e-101.973e-09

The five sigma standard used in particle physics corresponds to a one-sided probability of about 1 in 3.5 million. Six sigma manufacturing allows for a 1.5 sigma process drift, so in practice it targets about 3.4 defects per million rather than the 1 in a billion the raw table implies.

11.12 Sample size and the standard error

When you score a sample mean rather than a single value, the denominator is the standard error. This table shows how quickly it shrinks, and why quadrupling your sample only halves your uncertainty.

n√nSE as a fraction of SD95% margin of error in SD units
42.000.50000.9800
93.000.33330.6533
164.000.25000.4900
255.000.20000.3920
366.000.16670.3267
497.000.14290.2800
648.000.12500.2450
10010.000.10000.1960
14412.000.08330.1633
22515.000.06670.1307
40020.000.05000.0980
100031.620.03160.0620

Read the last column as: with n = 25 a 95% interval reaches 0.392 standard deviations either side of the sample mean. Going from n = 25 to n = 100 halves that to 0.196, which is why sample size has diminishing returns.

11.13 The same calculation in five packages

TaskExcelRPythonSPSSStata
MeanAVERAGE(r)mean(x)x.mean()DESCRIPTIVESsummarize x
Sample SDSTDEV.S(r)sd(x)x.std(ddof=1)DESCRIPTIVESsummarize x
Population SDSTDEV.P(r)sd(x)*sqrt((n-1)/n)x.std()not directsummarize x
Standardise a variableSTANDARDIZE(x,m,s)scale(x)stats.zscore(x,ddof=1)DESCRIPTIVES /SAVEegen z=std(x)
Percentile from zNORM.S.DIST(z,TRUE)pnorm(z)stats.norm.cdf(z)CDF.NORMAL(z,0,1)normal(z)
Z from percentileNORM.S.INV(p)qnorm(p)stats.norm.ppf(p)IDF.NORMAL(p,0,1)invnormal(p)
Two-tailed p2*(1-NORM.S.DIST(ABS(z),TRUE))2*pnorm(-abs(z))2*stats.norm.sf(abs(z))2*(1-CDF.NORMAL(ABS(z),0,1))2*normal(-abs(z))
MedianMEDIAN(r)median(x)np.median(x)FREQUENCIESsummarize x, detail
Default SD divisoryou choosen − 1nn − 1n − 1
Read the last row twice. R, SPSS and Stata all default to n − 1, while NumPy, scipy.stats.zscore and scikit-learn's StandardScaler all default to n. That single inconsistency is the most common reason two analysts get different z-scores from identical data.

11.14 Choosing an outlier method

MethodFormulaThresholdRobust?Minimum useful nBest for
Ordinary z-score(x − mean) / SD|z| > 3NoAbout 30Large, roughly normal samples
Modified z-score0.6745(x − median) / MAD|M| > 3.5YesAbout 10Small samples, suspected masking
Tukey IQR ruleoutside Q1 − 1.5×IQR to Q3 + 1.5×IQRfixedYesAbout 8Exploratory work, boxplots
Grubbs testmax|x − mean| / SDtable of critical valuesNo7Testing one suspected outlier formally
Percentile trimmingdrop below 1st or above 99thchosen in advanceYesAbout 100Large datasets, automated pipelines
Isolation foresttree-based anomaly scorecontamination rateYesSeveral hundredMany variables at once

11.15 Reading the sign and size at a glance

Z-score rangePlain-English descriptionRoughly how often in normal dataWhat to do
|z| below 0.5Essentially averageAbout 38% of valuesNothing. This is the middle of the distribution
0.5 to 1.0Slightly above or below averageAbout 30% of valuesNothing. Still entirely ordinary
1.0 to 2.0Noticeably high or lowAbout 27% of valuesWorth mentioning, not worth investigating
2.0 to 2.5UncommonAbout 4% of valuesNote it. Check the measurement if it matters
2.5 to 3.0RareAbout 1% of valuesInspect the original record
Above 3.0Very rareAbout 0.27% of valuesInspect, and check the modified z-score too
Above 5.0Almost certainly not chanceAbout 1 in 1.7 millionSuspect a data-entry or unit error first

These frequencies apply to a normal distribution only. On skewed data, values with |z| above 3 can be entirely common, which is why chart 3 in the results section matters before you use this table.

💡 12. Eight Worked Examples

Every number below was computed with the calculator on this page, using the sample standard deviation and a two-tailed p-value unless stated otherwise. Each example has its own colour and its own figure showing where the value falls on the normal curve. Paste any dataset into the tool and you will reproduce the result exactly.

1📝 Example 1, Exam Marks

Data: 52, 48, 55, 61, 47, 58, 50, 63, 45, 56, 54, 49
Value scored: 61

-4-3-2-10+1+2+3+4z = 1.381every observation plotted as a z-scoreExam marks, n = 12two-tailed p = 0.1671
Figure 1. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
n12
Mean53.1667
SD (sample)5.6702
Z-score1.3815
Percentile91.64
Two-tailed p0.1671
Median53.0
MAD4.5
Modified z1.1991

Reading it: A mark of 61 sits 1.38 standard deviations above the class mean, roughly the 92nd percentile. The two-tailed p of 0.167 says a mark this far from the mean is not unusual. Note the ceiling: with n = 12 the largest z any mark could reach is 3.18, so the |z| > 3 rule has almost no room to work here.

2🧠 Example 2, IQ Score, Known Population Parameters

Data: mean 100, SD 15 (published norms, so population values)
Value scored: 148

-4-3-2-10+1+2+3+4z = 3.200IQ score, population parameters knownpercentile 99.93
Figure 2. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
μ100
σ15
x148
Z-score3.2000
Percentile99.93
Two-tailed p0.00137
Rarityabout 1 in 1455

Reading it: This is the cleanest possible case, because the mean and SD are genuinely known rather than estimated. A z of 3.2 puts the score above roughly 99.93% of the population, or about 1 person in 1,450. The percentile is trustworthy here precisely because IQ scores are constructed to be normally distributed.

3🔧 Example 3, Manufacturing Tolerance

Data: 12.1, 11.8, 12.4, 12.0, 11.9, 12.3, 12.2, 11.7, 12.5, 12.0, 11.6, 12.6, 12.1, 11.95, 12.35
Value scored: 12.6

-4-3-2-10+1+2+3+4z = 1.711every observation plotted as a z-scoreComponent length in mm, n = 15all parts inside 3 sigma
Figure 3. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
n15
Mean12.1000
SD (sample)0.2922
Z-score1.7114
Percentile95.65
Two-tailed p0.0870

Reading it: The largest part is 1.71 SD above the mean, comfortably inside a typical ±3 SD control limit. In process control the z-score is the natural language: specification limits are usually expressed as a number of standard deviations, and a six sigma process is simply one where the nearest limit sits at z = 6.

4🚨 Example 4, A Real Outlier, and Why Ordinary Z Nearly Missed It

Data: 120, 118, 125, 119, 122, 121, 117, 124, 123, 119, 126, 116, 121, 120, 118, 180
Value scored: 180

-4-3-2-10+1+2+3+4ceiling 3.75z = 3.683every observation plotted as a z-scoreHeart rate in bpm, n = 16, one extreme valueceiling 3.75, observed z 3.68
Figure 4. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
n16
Mean124.3125
SD (sample)15.1205
SD without the 1802.9472
Z-score3.6829
Max possible |z|3.75
Median120.5
MAD2.5
Modified z16.05

Reading it: This is the single most instructive example on the page. The ordinary z is 3.68, only just past the usual threshold, because the outlier inflated the standard deviation from 2.95 to 15.12 and thereby disguised itself. The modified z-score, built from the median and MAD, returns 16.05, an unmistakable flag. Also notice the ceiling for n = 16 is 3.75, marked as the dashed line in the figure, so this value came within a whisker of being uncatchable by the ordinary rule no matter how extreme it was.

5📏 Example 5, Small Sample Where the Rule Cannot Fire

Data: 3.2, 3.5, 3.1, 3.8, 3.4, 3.6, 3.3, 3.7, 3.45, 3.55
Value scored: 3.8

-4-3-2-10+1+2+3+4ceiling 2.85z = 1.557every observation plotted as a z-scoreSleep duration in hours, n = 10nothing can ever reach z = 3
Figure 5. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
n10
Mean3.4600
SD (sample)0.2183
Z-score1.5573
Percentile94.03
Max possible |z|2.85

Reading it: With ten observations the largest z-score arithmetically possible is 2.85, shown as the dashed ceiling line well to the left of z = 3. No value in this dataset can ever be flagged, so screening it with the |z| > 3 rule guarantees zero detections regardless of the data. Use the modified z-score at any sample size below about thirty.

6📊 Example 6, Z for a Sample Mean

Data: population mean 500, population SD 100, sample mean 512 from n = 64
Value scored: 512 (a mean, not one value)

-4-3-2-10+1+2+3+4z = 0.960Sample mean of 64 observationsdivided by SE = 12.5, not SD = 100
Figure 6. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
Standard error100 ÷ √64 = 12.5
Z-score0.9600
Percentile83.15
Two-tailed p0.3371
If you wrongly used SDz = 0.12

Reading it: The denominator is the standard error, 12.5, not the standard deviation of 100. Had you wrongly divided by 100 you would have got z = 0.12 and concluded the sample was utterly ordinary. Even done correctly, p = 0.337 gives no evidence the sample came from a population with a different mean.

7🎓 Example 7, Standardising a Class for Comparison

Data: 88, 92, 79, 85, 95, 73, 90, 84, 81, 87, 94, 76, 89, 83, 91, 80, 86, 93, 77, 82
Value scored: 95

-4-3-2-10+1+2+3+4z = 1.538every observation plotted as a z-scoreTest scores, n = 20top scorer at the 93.8th percentile
Figure 7. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
n20
Mean85.2500
SD (sample)6.3401
Z-score1.5378
Percentile93.80
Two-tailed p0.1241
Same student, harder paper68 with M 55, SD 9 gives z = 1.4444

Reading it: The top scorer is 1.54 SD above the class mean. The point of standardising is comparison: the same student scoring 68 on a harder paper with mean 55 and SD 9 gives z = 1.44, so the two performances are almost identical despite the raw marks differing by 27 points.

8🔄 Example 8, Reverse Lookup

Data: mean 500, SD 100. Question: what value marks the 90th percentile?
Value scored: the cut-off is what we are solving for

-4-3-2-10+1+2+3+4z = 1.282Finding the 90th percentile cut-offshaded area = 90%
Figure 8. Standard normal curve with the shaded p-value region, the empirical-rule bands, and this example's z-score marked.
Percentile wanted90%
Z for that percentile1.2816
Raw value500 + 1.2816 × 100 = 628.16
Excel=NORM.S.INV(0.9)
Rqnorm(0.9)
Pythonstats.norm.ppf(0.9)

Reading it: The reverse mode answers cut-off questions: the pass mark for the top decile, the reorder level that covers 90% of demand, the threshold that captures the top 10% of applicants. The shaded region in the figure is the 90% of the distribution that falls below the cut-off.

📋 13. Data Collection Protocol

A z-score is only as good as the mean and standard deviation behind it, and both are easy to compromise before you ever open a calculator. This is the protocol that keeps them honest.

  1. Define the reference population before you collect anything. A z-score answers "unusual compared with what". Compared with this year's cohort, or all cohorts? Compared with this machine, or the whole production line? The answer determines which mean and SD you should be using, and it cannot be decided afterwards.
  2. Decide whether you have a population or a sample. If you measured every unit that exists in your defined population, use the population SD. In almost every real study you have a sample, so use n minus 1.
  3. Use a single measurement protocol throughout. Same instrument, same units, same operator instructions, same time of day where it matters. Mixing two measurement methods inflates the SD and shrinks every z-score, which quietly hides genuine outliers.
  4. Record raw values, never rounded ones. Rounding to the nearest whole number before computing an SD can shift z-scores in the second decimal place. Round at the reporting stage only.
  5. Log every exclusion at the moment it happens. Instrument failure, protocol violation, participant withdrawal. Write down what and why. Reviewers will compare your stated n against your reported one.
  6. Aim for n of at least 30 if outlier screening is a goal. Below that the |z| > 3 rule is mathematically hobbled by the ceiling. If a small sample is unavoidable, plan to use the modified z-score and say so in your methods.
  7. Check for the units trap. Z-scores are unitless, which is their strength, but the mean and SD must come from data in one consistent unit. One row in grams among a column of kilograms will not throw an error, it will just produce a spectacular false outlier.
  8. Screen for normality before you rely on percentiles. A histogram and a Q-Q plot take thirty seconds. If the data are clearly skewed, plan to report the z-score as a distance in standard deviations and drop the percentile claim.
  9. Keep the raw data file untouched. Do all cleaning in a script or a copy so that any z-score can be traced back to the original record. When a value is flagged, you will want to look at the original entry.
  10. Store the mean, SD and n alongside the z-scores. A column of z-scores with no record of what standardised them is uninterpretable and cannot be back-transformed.
The most common protocol failure. Standardising a training set and a test set separately, so the two are on different scales, or standardising the combined set and leaking test information into training. Fit once on training data, then apply those stored values everywhere else.

🎯 14. When to Use a Z-Score, and When Not To

Use a z-score when

  • You need to compare measurements on different scales. This is the original purpose. Height in centimetres against weight in kilograms, an essay mark against a maths mark, revenue in one currency against another.
  • You want a percentile from a roughly normal distribution. Test scores, measurement error, biological measurements within a defined group.
  • You are standardising features before modelling. Regularised regression, k-nearest neighbours, principal component analysis, neural networks and anything using gradient descent all behave badly when features have wildly different scales.
  • You are screening a reasonably large sample for outliers. Above about n = 30 the ordinary rule becomes usable, though the modified version is still safer.
  • The population mean and SD are genuinely known. Standardised tests, published growth charts, calibrated instruments. This is the case textbooks assume and the case where the percentile is most trustworthy.
  • You need a cut-off from a percentile. The reverse direction: what value marks the top 5%, what stock level covers 95% of demand.

Do not use a z-score when

  • The data are strongly skewed and you want a percentile. Income, waiting times, species abundance, insurance claims. The z-score is still a valid distance but the normal percentile attached to it will be wrong. Use the empirical percentile rank instead.
  • The sample is small and you are hunting outliers. Below n = 11 the |z| > 3 rule cannot fire at all. Use the modified z-score.
  • The data are ordinal. Likert responses, rankings, categories with an order. The mean and SD of an ordinal scale are not well defined, so neither is the z-score.
  • The standard deviation is zero or near zero. If every value is identical the z-score is undefined. If they are nearly identical, tiny differences become enormous z-scores.
  • You are testing a sample mean with an estimated SD and a small n. That is a t-test, not a z-test. The t-distribution has heavier tails and gives more honest p-values below about n = 30.
  • The distribution has two peaks. A bimodal dataset has a mean sitting in the empty valley between the groups, so every z-score is measured from a value that no observation resembles.
  • You want to say something about the reliability of the estimate. A z-score carries no uncertainty of its own and no information about sample size. Use a confidence interval for that.

What to use instead

SituationBetter choiceWhy
Skewed data, need a percentileEmpirical percentile rankMakes no distributional assumption
Small sample outlier screeningModified z-score, threshold 3.5Median and MAD cannot be inflated by the outlier
Outliers in a boxplot context1.5 × IQR ruleAlso robust, and standard in exploratory work
Testing a mean, SD estimated, n smallOne-sample t-testAccounts for the extra uncertainty in the estimated SD
Comparing spread across different scalesCoefficient of variationRelative rather than absolute variability
Heavy skew before any analysisLog or Box-Cox transform, then standardiseRestores approximate normality first
Robust scaling for machine learningRobustScaler (median and IQR)Outliers do not distort the scaling

🔧 15. Troubleshooting

SymptomCauseFix
Z-score is undefined or the tool refuses to runStandard deviation is zero, so every value equals the meanThere is no z-score to compute. Check that your data actually vary
Every z-score is enormousNear-zero SD, or one value entered in the wrong unitLook at the raw data. A single gram among kilograms does this
Your answer differs from a colleague's in the third decimalOne of you used n and the other n minus 1Agree on sample or population and state it in the methods
R and Python disagreesd() uses n minus 1, np.std() defaults to nWrite ddof=1 in NumPy
No outliers found, but the data clearly contain oneThe outlier inflated the SD and hid itself, or n is below the ceilingUse the modified z-score with a 3.5 threshold
Percentile looks wrong for your dataThe data are not normal, so the normal curve mapping failsReport the z-score as a distance, or use an empirical percentile
P-value is half what you expectedOne-tailed instead of two-tailedChoose the tail before seeing the data, and state which you used
Excel returns #VALUE!Text or blanks inside the range, or FALSE passed to NORM.S.DISTClean the range and pass TRUE for cumulative probability
Excel z-scores drift as you drag down the columnMissing dollar signs on the mean and SD referencesUse $E$2 and $E$3
Modified z-score is infiniteMAD is zero because more than half the values are identicalThe data are too discrete for this method. Use the IQR rule
R's mad() gives a different modified zR's mad() already multiplies by 1.4826Compute median(abs(x - median(x))) directly
Z-score for a sample mean looks far too smallDivided by the SD instead of the standard errorDivide by SD over the square root of n
Model accuracy dropped after standardisingScaler fitted on the full dataset, leaking test informationFit on training data only, then transform the test set
CSV upload produced empty columnsNon-numeric characters such as currency symbols or thousands separatorsStrip them before uploading, or select a different column
Two groups have the same z-score but look very differentDifferent means and SDs produce identical standardised positionsAlways report the mean, SD and n alongside the z-score

16. Assumptions and Limitations

What the z-score assumes

AssumptionNeeded forWhat happens if it fails
Data are numeric on an interval or ratio scaleThe z-score itselfThe mean and SD are undefined for ordinal or nominal data
Standard deviation is greater than zeroThe z-score itselfDivision by zero. No z-score exists
Data are approximately normalPercentile and p-value onlyThe z-score stays correct; the percentile can be badly wrong
Mean and SD represent the right reference populationAny interpretationThe z-score answers a different question than you asked
Observations are independentP-valuesClustered or repeated measures give p-values that are too small
Population σ is knownA formal z-testWith an estimated SD and small n, use a t-test instead
Sample is large enoughOutlier screeningThe ceiling makes the |z| > 3 rule unable to fire

Limitations you should state in a write-up

  • The percentile depends entirely on normality. The z-score does not, and the two are often conflated. Be explicit about which claim you are making.
  • The mean and SD are not robust. A single extreme value moves both, so every z-score in the dataset shifts because of one observation.
  • The ceiling on small samples is a hard mathematical limit, not a statistical convention. It cannot be argued around.
  • A z-score carries no uncertainty. It is a point description with no confidence interval attached and no sensitivity to sample size.
  • Standardising does not fix skew. It shifts and rescales the distribution but leaves its shape untouched. A skewed variable is still skewed after standardising.
  • Comparability requires a shared reference. Two z-scores computed against different populations are not directly comparable, however similar the numbers look.
  • Extreme z-scores are not evidence of error. They flag values worth inspecting, nothing more. The decision to exclude is a scientific judgement, not a statistical one.

🏁 17. Conclusion

The z-score is one of the smallest ideas in statistics and one of the most widely used. Subtract the mean, divide by the standard deviation, and you have converted a measurement in any unit into a position on a common scale. That single operation is what lets an exam mark be compared with an essay grade, a machine tolerance with a laboratory assay, and a height measurement with a weight measurement. It is the reason standardisation appears in almost every statistical method that combines variables.

Its interpretation is equally compact. The sign gives the direction, the magnitude gives the distance in standard deviations, and the empirical rule supplies rough landmarks: about 68% of a normal distribution lies within one standard deviation of the mean, about 95% within two, about 99.7% within three. A z of 2 is therefore uncommon and a z of 3 is rare, in a normal distribution.

That last qualification is where most misuse begins. The z-score itself assumes nothing, but the moment you convert it into a percentile or a p-value you are reading off the normal curve, and if your data are skewed those numbers are wrong even though the z-score is right. Check a histogram before you quote a percentile. If the shape is not roughly symmetric, report the z-score as a distance and use an empirical percentile rank instead.

The second failure is subtler and far more common: using the |z| > 3 rule to find outliers in a small sample. The largest z-score attainable in a sample of n is (n − 1) divided by the square root of n. With ten observations that ceiling is 2.85, so the rule cannot fire no matter how extreme a value is. Worse, an outlier inflates the standard deviation used to compute its own z-score, disguising itself even when the sample is large enough. Example 4 on this page shows exactly that: a heart rate of 180 among readings in the 120s gives an ordinary z of 3.68, barely past the threshold, while the modified z-score built from the median and MAD returns 16.05. Whenever you are screening for outliers, particularly below about n = 30, use the modified z-score with a threshold of 3.5.

Three further habits will keep your results defensible. Decide sample or population once and stay with it, because the difference between STDEV.S and STDEV.P propagates through every number downstream and is the usual reason two people get slightly different answers. Choose your p-value tail before you look at the data, not after. And always report the mean, standard deviation and n alongside any z-score, because the same z means entirely different things depending on the distribution it came from, and without those three numbers nobody, including you in six months, can reconstruct what you did.

Used with those caveats, the z-score remains what it has been since Fisher and Pearson formalised it: the simplest honest way to say how unusual a number is.

18. Frequently Asked Questions

What is a z-score in simple terms?
A z-score tells you how many standard deviations a value sits above or below the mean. A z of +2 means the value is two standard deviations above average; a z of −1 means one standard deviation below. Zero means exactly average. Because the standard deviation sets the scale, the same z-score means the same thing no matter what you measured or in what units.
What is the formula for a z-score?
z = (x − μ) ÷ σ, where x is the value, μ is the mean and σ is the standard deviation. When you are working from a sample rather than a whole population, substitute the sample mean and the sample standard deviation. For a sample mean rather than a single value, the denominator becomes the standard error, σ divided by the square root of n.
Is a high z-score good or bad?
Neither by itself. The z-score only reports position, not desirability. A z of +2 on an exam is excellent; a z of +2 on blood pressure or on a manufacturing defect rate is a problem. The direction that counts as good depends entirely on what you measured.
What z-score counts as an outlier?
The common rule is |z| > 3, sometimes |z| > 2.5. But the rule is unreliable on small samples, because the largest z-score attainable in a sample of n is (n − 1) divided by the square root of n. With ten observations that ceiling is 2.85, so nothing can ever be flagged. Below about n = 30 use the modified z-score with a threshold of 3.5 instead.
What is a modified z-score?
It replaces the mean with the median and the standard deviation with the median absolute deviation: M = 0.6745 × (x − median) ÷ MAD. Because neither the median nor the MAD can be distorted by an extreme value, the modified z-score does not suffer the self-masking problem of the ordinary version. Iglewicz and Hoaglin (1993) recommend flagging values above 3.5 in absolute terms.
Can a z-score be negative?
Yes, and it simply means the value is below the mean. Negative z-scores are not worse than positive ones, they just point in the other direction. About half of any dataset will have a negative z-score, since roughly half the values sit below the mean.
What is the maximum possible z-score?
In theory a z-score is unbounded, but within a finite sample of size n the largest attainable value is (n − 1) divided by the square root of n. For n = 5 that is 1.79, for n = 10 it is 2.85, for n = 30 it is 5.29, and for n = 100 it is 9.90. This is a hard arithmetic limit and the reason the |z| > 3 outlier rule fails on short datasets.
How do I convert a z-score to a percentile?
Read the cumulative area to the left of z from a standard normal table, or use NORM.S.DIST(z, TRUE) in Excel, pnorm(z) in R, or stats.norm.cdf(z) in Python. A z of 1.5 gives about 0.9332, so the 93rd percentile. This conversion assumes the data are normally distributed; on skewed data the percentile will be wrong even though the z-score is correct.
What is the difference between a z-score and a t-score?
A z-score uses the known population standard deviation and follows the normal distribution. A t-score uses an estimated standard deviation from a sample and follows the t-distribution, which has heavier tails to account for that extra uncertainty. With samples above about 30 the two converge. Below that, using z when you should use t gives p-values that are too small.
Should I use n or n minus 1 for the standard deviation?
Use n minus 1, the sample standard deviation, unless you genuinely measured every member of the population. This is Excel's STDEV.S, R's sd() and NumPy's ddof=1. The population version divides by n and gives a slightly smaller standard deviation, hence slightly larger z-scores. Pick one and use it consistently, because this is the single most common reason two people get different answers from the same data.
Why do R and Python give me different z-scores?
Because their defaults differ. R's sd() always divides by n minus 1, while NumPy's np.std() defaults to dividing by n. So does scipy.stats.zscore() and scikit-learn's StandardScaler. Add ddof=1 in Python to match R.
Do my data have to be normally distributed?
Not for the z-score itself, which is pure arithmetic and is valid on any numeric data. Normality is required only when you convert the z-score into a percentile or a p-value, because that step reads off the normal curve. On strongly skewed data, report the z-score as a distance in standard deviations and use an empirical percentile rank instead.
What is the empirical rule?
In a normal distribution, about 68% of values lie within one standard deviation of the mean, about 95% within two, and about 99.7% within three. It is often called the 68-95-99.7 rule. The precise figures are 68.27%, 95.45% and 99.73%. Note that the familiar 95% confidence figure corresponds to z = 1.96, not exactly 2.
How do I calculate a z-score in Excel?
Either write the formula directly as =(A2-$E$2)/$E$3, or use the built-in =STANDARDIZE(A2, mean, sd). Get the mean with =AVERAGE(range) and the standard deviation with =STDEV.S(range) for a sample. The dollar signs matter: without them the references slide as you drag the formula down.
What does a z-score of 0 mean?
The value is exactly equal to the mean. It is the 50th percentile of a normal distribution, and it means the observation is perfectly typical for that dataset. It says nothing about whether the mean itself is high or low in any absolute sense.
How do I find the raw value from a z-score?
Rearrange the formula: x = μ + zσ. If you have a percentile rather than a z-score, first convert it with NORM.S.INV in Excel, qnorm() in R or stats.norm.ppf() in Python. For example the 95th percentile is z = 1.6449, so with a mean of 500 and SD of 100 the cut-off is 664.49.
What is a z-test and how does it relate to a z-score?
A z-test compares a sample mean against a known population mean, using z = (x̄ − μ) ÷ (σ ÷ √n). The denominator is the standard error, not the standard deviation, because sample means vary less than individual values do. It requires a known population standard deviation; if you estimated it from the sample and n is small, use a one-sample t-test instead.
Can I compare z-scores from two different datasets?
Only if they were standardised against comparable reference populations. Two z-scores of 1.5 computed against different groups mean "1.5 standard deviations above that group's mean", and those groups may be nothing alike. Always report the mean, SD and n so readers can judge whether the comparison is fair.
Why should I standardise features before machine learning?
Algorithms that measure distance or use gradient descent, such as k-nearest neighbours, support vector machines, principal component analysis and neural networks, are dominated by whichever feature has the largest numeric range. Standardising puts every feature on the same scale. Fit the scaler on the training set only and apply those stored values to the test set, otherwise you leak test information into training.
What is the difference between a z-score and a percentile rank?
A z-score is a distance from the mean measured in standard deviations, and it can be converted to a percentile only by assuming normality. A percentile rank is computed directly from the data by counting how many values fall below a given observation, and it makes no distributional assumption at all. On skewed data the empirical percentile rank is the honest choice.

🔖 19. Cite This Tool

APA 7th
StatsUnlock. (2026). Z-Score Calculator [Online tool]. https://statsunlock.com/z-score-calculator/
MLA 9th
"Z-Score Calculator." StatsUnlock, 2026, statsunlock.com/z-score-calculator/.
Chicago
StatsUnlock. "Z-Score Calculator." Accessed 2026. https://statsunlock.com/z-score-calculator/.
BibTeX
@misc{statsunlock_zscore, title={Z-Score Calculator}, author={{StatsUnlock}}, year={2026}, url={https://statsunlock.com/z-score-calculator/}}

🔗 20. Related Calculators

📖 21. Glossary

TermMeaning
Z-scoreThe number of standard deviations a value lies above or below the mean. Also called a standard score.
Standard scoreAnother name for a z-score.
StandardisationConverting a variable so it has mean 0 and standard deviation 1, by computing the z-score of every value.
Standard normal distributionA normal distribution with mean 0 and standard deviation 1. Every z-score lives on this scale.
μ (mu)The population mean.
σ (sigma)The population standard deviation.
x̄ (x-bar)The sample mean.
sThe sample standard deviation, computed with n minus 1.
Bessel's correctionDividing by n minus 1 instead of n when estimating a variance from a sample, which removes downward bias.
Degrees of freedom (ddof)The parameter that controls whether software divides by n or n minus 1. R fixes it at 1, NumPy defaults to 0.
Standard errorThe standard deviation of a sample mean, σ divided by the square root of n. Used when scoring a mean rather than a single value.
Φ (Phi)The standard normal cumulative distribution function, giving the area to the left of a z-score.
PercentileThe percentage of the distribution falling below a given value.
Percentile rankA percentile computed directly by counting data, with no normality assumption.
P-valueThe probability of observing a value at least this extreme if the null model is true.
Two-tailed testCounts extreme values in both directions. The default when you simply want to know whether a value is unusual.
One-tailed testCounts extremes in one direction only. Must be chosen before seeing the data.
Critical valueThe z-score marking the boundary of a rejection region, such as 1.96 for a two-tailed test at alpha 0.05.
Empirical ruleThe 68-95-99.7 approximation for how much of a normal distribution lies within one, two and three standard deviations of the mean.
OutlierAn observation far from the rest of the data. Unusual, not necessarily wrong.
MaskingWhen an outlier inflates the standard deviation enough to keep its own z-score below the detection threshold.
MADMedian absolute deviation, the median of the absolute distances from the median. A robust measure of spread.
Modified z-score0.6745 × (x − median) ÷ MAD. A robust alternative that outliers cannot distort.
Robust statisticOne whose value is barely affected by a small number of extreme observations.
SkewnessAsymmetry in a distribution. Skewed data break the percentile interpretation of a z-score.
Z-testA hypothesis test comparing a sample mean against a known population mean using a known population standard deviation.
T-scoreThe analogue of a z-score when the standard deviation is estimated from the sample, following the t-distribution.
Q-Q plotA diagnostic plot comparing your data's quantiles against a normal distribution's, used to check normality.

📚 22. References

  1. Iglewicz, B., & Hoaglin, D. C. (1993). How to Detect and Handle Outliers. ASQC Quality Press. asq.org
  2. Shiffler, R. E. (1988). Maximum Z scores and outliers. The American Statistician, 42(1), 79-80. doi.org/10.1080/00031305.1988.10475530
  3. Leys, C., Ley, C., Klein, O., Bernard, P., & Licata, L. (2013). Detecting outliers: Do not use standard deviation around the mean, use absolute deviation around the median. Journal of Experimental Social Psychology, 49(4), 764-766. doi.org/10.1016/j.jesp.2013.03.013
  4. Rousseeuw, P. J., & Croux, C. (1993). Alternatives to the median absolute deviation. Journal of the American Statistical Association, 88(424), 1273-1283. doi.org/10.1080/01621459.1993.10476408
  5. Grubbs, F. E. (1969). Procedures for detecting outlying observations in samples. Technometrics, 11(1), 1-21. doi.org/10.1080/00401706.1969.10490657
  6. Tukey, J. W. (1977). Exploratory Data Analysis. Addison-Wesley. archive.org
  7. Moore, D. S., McCabe, G. P., & Craig, B. A. (2021). Introduction to the Practice of Statistics (10th ed.). W. H. Freeman. macmillanlearning.com
  8. Field, A. (2024). Discovering Statistics Using IBM SPSS Statistics (6th ed.). SAGE. sagepub.com
  9. Barnett, V., & Lewis, T. (1994). Outliers in Statistical Data (3rd ed.). Wiley. wiley.com
  10. Abramowitz, M., & Stegun, I. A. (1964). Handbook of Mathematical Functions. National Bureau of Standards. personal.math.ubc.ca
  11. Press, W. H., Teukolsky, S. A., Vetterling, W. T., & Flannery, B. P. (2007). Numerical Recipes: The Art of Scientific Computing (3rd ed.). Cambridge University Press. numerical.recipes
  12. Acklam, P. J. (2003). An algorithm for computing the inverse normal cumulative distribution function. Archived notes
  13. Wicklin, R. (2011). What is a z-score? What is a p-value? SAS Blogs, The DO Loop. blogs.sas.com
  14. Wilkinson, L., & the Task Force on Statistical Inference (1999). Statistical methods in psychology journals: Guidelines and explanations. American Psychologist, 54(8), 594-604. doi.org/10.1037/0003-066X.54.8.594
  15. American Psychological Association (2020). Publication Manual of the American Psychological Association (7th ed.). apastyle.apa.org
  16. Ghasemi, A., & Zahediasl, S. (2012). Normality tests for statistical analysis: A guide for non-statisticians. International Journal of Endocrinology and Metabolism, 10(2), 486-489. doi.org/10.5812/ijem.3505
  17. Kuhn, M., & Johnson, K. (2019). Feature Engineering and Selection: A Practical Approach for Predictive Models. CRC Press. bookdown.org/max/FES
  18. Pedregosa, F., et al. (2011). Scikit-learn: Machine learning in Python. Journal of Machine Learning Research, 12, 2825-2830. jmlr.org
  19. Virtanen, P., et al. (2020). SciPy 1.0: Fundamental algorithms for scientific computing in Python. Nature Methods, 17, 261-272. doi.org/10.1038/s41592-019-0686-2
  20. R Core Team (2024). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing. r-project.org
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Important Plots & Charts

Most Popular