devnotes.

Inspecting the Data: shape, info, describe

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:

ObservationMeaning
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 smallalmost 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.

Inspecting the Data: shape, info, describe | Exploratory Data Analysis | DevNotes