Why Data Types Come First
Before you calculate anything, decide what kind of data each column holds. The type tells you which summaries and charts make sense. If you get it wrong, a spreadsheet will still give you an answer. The answer will just mean nothing, like an "average postcode".
Think of data types like the labels on a toolbox drawer. A spanner is no use on a screw, and an average is no use on a column of shop names.
The Four Types
Every column is one of two families, and each family splits in two.
Categorical columns put each row into a group.
- Nominal: the groups have no natural order. Examples: region, product colour, payment method.
- Ordinal: the groups have a meaningful order, but the gaps between them are not equal or measured. Examples: Small < Medium < Large, or a satisfaction score from 1 to 5. A score of 4 is better than 2, but it is not "twice as satisfied".
Numerical columns measure or count a quantity, so arithmetic on them means something.
- Discrete: counts in whole steps. Examples: units sold, number of complaints. You cannot sell 2.5 orders.
- Continuous: can take any value in a range, limited only by how precisely you measure. Examples: weight, delivery time, order value. Money is strictly counted in pennies, but analysts usually treat it as continuous because the steps are so small.
The Working Dataset
Type this into a new sheet, starting in cell A1:
| order_id | product_id | region | size | satisfaction | units | order_value |
|---|---|---|---|---|---|---|
| 1001 | 40217 | North | Small | 4 | 2 | 18.50 |
| 1002 | 40388 | South | Large | 5 | 1 | 42.00 |
| 1003 | 40217 | East | Medium | 2 | 3 | 27.75 |
| 1004 | 40951 | North | Large | 3 | 1 | 39.99 |
| 1005 | 40388 | West | Small | 5 | 4 | 36.20 |
| 1006 | 40951 | South | Medium | 1 | 2 | 25.10 |
Task 1: Label Every Column
Ask these questions about each column, in this order:
- Would arithmetic on it mean something? Try adding two values. If the sum means nothing, the column is categorical, even when it holds digits.
- If categorical: do the groups have a natural order? Yes means ordinal, no means nominal.
- If numerical: is it a count in whole steps? Yes means discrete. If it can take any value in a range, it is continuous.
- Write the label and a one-line reason next to the column name.
Applied to our data:
region: nominal. North is not "more" than West.size: ordinal. Small < Medium < Large.satisfaction: ordinal. The values are ordered, but the gap between 1 and 2 is not shown to equal the gap between 4 and 5.units: discrete. It counts whole items.order_value: continuous. Money is treated as a measured amount.order_idandproduct_id: see the next task.
Task 2: Spot Numbers That Are Really Categories
IDs, postcodes, phone numbers and account codes are labels written in digits. The test is simple: does adding two of them give something meaningful? Product 40217 + product 40388 is not a product. So the "average product ID" (about 40519) is a number with no meaning.
Treat these columns as nominal. Two practical warnings:
- Leading zeros vanish. A store code such as 0412, stored as a number, becomes 412. Store codes like this as text.
- Software cannot tell meaning from storage. A spreadsheet will happily total a column of IDs. Only you can know that the total is nonsense.
Task 3: Check How the Spreadsheet Stores Each Column
ISNUMBER(value) returns TRUE if a cell holds a number and FALSE for text, blanks or errors. It works in both Excel and Google Sheets.
- In cell H2, enter
=ISNUMBER(A2), then copy it across to N2. - Read the results:
order_id,product_id,satisfaction,unitsandorder_valueshow TRUE.regionandsizeshow FALSE. - Compare this with your labels. TRUE only means the cell is stored as a number. It does not mean the column is numerical.
order_idis TRUE but nominal. - Watch for the reverse problem too. A number stored as text, such as one pasted in with a leading apostrophe, returns FALSE, so sums and formulas will skip it.
Task 4 (Optional): Check Types in Python
import pandas as pd
df = pd.DataFrame({
"order_id": [1001, 1002, 1003, 1004, 1005, 1006],
"product_id": [40217, 40388, 40217, 40951, 40388, 40951],
"region": ["North", "South", "East", "North", "West", "South"],
"size": ["Small", "Large", "Medium", "Large", "Small", "Medium"],
"satisfaction": [4, 5, 2, 3, 5, 1],
"units": [2, 1, 3, 1, 4, 2],
"order_value": [18.50, 42.00, 27.75, 39.99, 36.20, 25.10],
})
print(df.dtypes)
DataFrame.dtypes lists the stored type of each column. IDs and integers show int64, order_value shows float64, and text columns show str in pandas 3.0 or later (object in older versions). As with ISNUMBER, the output describes storage, not meaning. Record the meaning yourself:
df = df.astype({"order_id": "str", "product_id": "str"})
df["size"] = pd.Categorical(df["size"],
categories=["Small", "Medium", "Large"], ordered=True)
When reading a CSV, pd.read_csv("file.csv", dtype={"store_code": str}) keeps leading zeros.
How Type Decides Summaries and Charts
- Nominal: counts and percentages per group, shown as a bar chart. No averages.
- Ordinal: counts per group, with bars kept in their natural order. Treat averages with caution.
- Discrete and continuous: totals, averages and other arithmetic are valid.
Closing Question
How many of the seven columns are categorical, and how many are numerical?
Check: the expected answer is 5 categorical (3 nominal, 2 ordinal) and 2 numerical (1 discrete, 1 continuous). Confirm it in Python:
labels = {"order_id": "nominal", "product_id": "nominal", "region": "nominal",
"size": "ordinal", "satisfaction": "ordinal",
"units": "discrete", "order_value": "continuous"}
cat = sum(v in ("nominal", "ordinal") for v in labels.values())
assert cat == 5 and len(labels) - cat == 2
In the spreadsheet, count your labels with =COUNTIF(range,"nominal")+COUNTIF(range,"ordinal"). This should return 5.
Key Takeaways
- Categorical columns are either nominal (no order) or ordinal (ordered). Numerical columns are either discrete (whole-step counts) or continuous (measured amounts).
- Test a column by asking whether arithmetic on it means anything.
- IDs and postcodes are nominal, even though they are written in digits.
- ISNUMBER and
df.dtypesshow how data is stored, not what it means. - The type decides which summaries and charts are valid.