Inspect a table

head, tail, sample, info, dtypes, describe, shape, and value counts.

Look before you group, join, or fill. Five glances catch most surprises: shape, dtypes, a few rows, numeric summary, and value counts on categories.

Goal

Reach for head, info, describe, and value_counts on every new table. Each block below is a complete script — paste it as the whole editor.

Rows and shape

df = pd.DataFrame(
    {
        "city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Nairobi"],
        "product": ["A", "B", "A", "B", "A"],
        "units": [12, 7, 9, 11, 5],
        "price": [10.5, 22.0, 10.5, 22.0, 10.5],
    }
)
df["revenue"] = df["units"] * df["price"]
print("shape", df.shape)
print()
print("head")
print(df.head(3))
print()
print("tail")
print(df.tail(2))
print()
print("random sample")
print(df.sample(2, random_state=1))

random_state makes the sample repeatable. shape is (rows, columns).

Types and info

df = pd.DataFrame(
    {
        "city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Nairobi"],
        "product": ["A", "B", "A", "B", "A"],
        "units": [12, 7, 9, 11, 5],
        "price": [10.5, 22.0, 10.5, 22.0, 10.5],
    }
)
print(df.dtypes)
print()
df.info()

info() writes to the console itself — you do not need to print it. Watch non-null counts; they reveal missing data.

Numeric summary

df = pd.DataFrame(
    {
        "city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Nairobi"],
        "product": ["A", "B", "A", "B", "A"],
        "units": [12, 7, 9, 11, 5],
        "price": [10.5, 22.0, 10.5, 22.0, 10.5],
    }
)
df["revenue"] = df["units"] * df["price"]
print(df.describe())
print()
print(df.describe(include="all"))

describe() defaults to numbers. include="all" adds object columns (count, unique, top, freq).

Counts

df = pd.DataFrame(
    {
        "city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Nairobi"],
        "product": ["A", "B", "A", "B", "A"],
        "units": [12, 7, 9, 11, 5],
        "price": [10.5, 22.0, 10.5, 22.0, 10.5],
    }
)
print(df["city"].value_counts())
print()
print(df["city"].value_counts(normalize=True).round(3))
print()
print("nunique product:", df["product"].nunique())
print("unique products:", df["product"].unique())

Memory and dimensions

df = pd.DataFrame(
    {
        "city": ["Nairobi", "Nairobi", "Mombasa"],
        "product": ["A", "B", "A"],
        "units": [12, 7, 9],
    }
)
print("size (cells):", df.size)
print(df.memory_usage(deep=True))
Tip

On a CSV you just uploaded, run print(df.head()), df.info(), and print(df.describe()) before any groupby. Garbage in, wrong totals out.