Inspecting the Data
Right after loading, ask four basic questions: How big is it? What types are the columns? What do the numbers look like? What are the columns called?
print(df.shape) # (1143, 13)
df.info() # dtypes, non-null counts, memory
print(df.describe().T) # count, mean, std, min, quartiles, max
print(df.columns.tolist()) # column names as a list
1. df.shape - size of the data
Returns a tuple (rows, columns). For WineQT it is (1143, 13): 1143 wines and 13 columns. Very small data (a few dozen rows) may not support complex models; huge data may need sampling for plotting.
2. df.info() - structure of the data
Shows, for every column: the name, the number of non-null values, and the dtype. It also prints memory usage.
What to look for:
- A numeric column stored as
object(text) - usually means bad characters such as"$"or",". - Non-null count lower than the number of rows - the column has missing values.
- A date stored as text - convert with
pd.to_datetime().
3. df.describe().T - statistical summary
By default it summarises numeric columns: count, mean, std, min, 25%, 50%, 75%, max. .T transposes the table so each variable is a row, which is easier to read when there are many columns.
How to read it:
| Observation | Meaning |
|---|---|
| mean much larger than median (50%) | right-skewed data, probably high outliers |
| max far above 75% | suspect outliers |
| min = 0 for a column like "pH" | impossible value, check data quality |
| std very small | almost constant column, may be useless |
To include text columns use df.describe(include="all"); for categorical columns use df["col"].value_counts().
4. df.columns.tolist() - column names
Converts the column index to a plain Python list. Useful for copying names, selecting subsets, or looping over columns:
num_cols = df.select_dtypes(include="number").columns.tolist()
cat_cols = df.select_dtypes(include="object").columns.tolist()
print(len(num_cols), "numeric,", len(cat_cols), "categorical")
Bonus checks
df["quality"].value_counts().sort_index() # class balance of the target
df.nunique() # unique values per column
df.dtypes.value_counts() # how many columns of each type
df.nunique() is especially useful: a column with only one unique value carries no information, and a numeric column with very few unique values is probably really categorical.