Pandas shape, size and ndim: Rows, Columns and Cells

Read shape, size and ndim without parentheses. Inspect table dimensions, distinguish cells from known values and reconcile rows after cleaning.

Create the student table 🔝

shape, size and ndim are attributes: use them without parentheses. Attributes and indexers have a different colour from function calls in the examples.

import pandas as pd
from io import StringIO, BytesIO
students = pd.DataFrame({
    "NAME": ["Ravi", "Raju", "Alex", "Ron", "King", "Jack"],
    "ID": [1, 2, 3, 4, 5, 6],
    "MATH": [80, 40, 70, 70, 70, 30],
    "ENGLISH": [80, 70, 40, 50, 60, 30]
})
print(students)

Expected output

   NAME  ID  MATH  ENGLISH
0  Ravi   1    80       80
1  Raju   2    40       70
2  Alex   3    70       40
3   Ron   4    70       50
4  King   5    70       60
5  Jack   6    30       30

Read the number of rows and columns 🔝

DataFrame.shape returns a tuple in the order rows, columns. It describes the current table, including rows with missing data.

print(students.shape)
print("Rows:", students.shape[0])
print("Columns:", students.shape[1])
rows, columns = students.shape
assert (rows, columns) == (6, 4)

Expected output

(6, 4)
Rows: 6
Columns: 4

Count cells with size 🔝

size equals rows multiplied by columns. It includes missing cells; it is neither a count of known values nor a memory measurement.

print("Cells:", students.size)
print("Rows times columns:", students.shape[0] * students.shape[1])
assert students.size == 24

Expected output

Cells: 24
Rows times columns: 24

Understand ndim for DataFrames and Series 🔝

A DataFrame has ndim=2 even with one column. A Series has ndim=1. Selecting with a list keeps a DataFrame; selecting one column label returns a Series.

series = students["NAME"]
one_column = students[["NAME"]]
print("DataFrame ndim:", students.ndim)
print("Series shape/ndim:", series.shape, series.ndim)
print("One-column DataFrame shape/ndim:", one_column.shape, one_column.ndim)
assert series.shape == (6,)
assert one_column.shape == (6, 1)

Expected output

DataFrame ndim: 2
Series shape/ndim: (6,) 1
One-column DataFrame shape/ndim: (6, 1) 2

Compare size with nonmissing counts 🔝

Use count() for known values and isna() for missing cells. An all-missing table still has rows, columns and cells.

table = pd.DataFrame({"A": [1.0, None, 3.0], "B": [None, 2.0, 4.0]})
known = int(table.count().sum())
missing = int(table.isna().sum().sum())
print("Shape:", table.shape, "Cells:", table.size)
print("Known cells:", known, "Missing cells:", missing)
assert table.size == known + missing == 6

Expected output

Shape: (3, 2) Cells: 6
Known cells: 4 Missing cells: 2

Distinguish an empty table from missing data 🔝

A table is empty when either axis has length zero. A table filled with missing values is not empty. Check the required columns and row count separately when validating a dataset.

for label, table in [
    ("No rows", pd.DataFrame(columns=["A", "B"])),
    ("No columns", pd.DataFrame(index=[0, 1, 2])),
    ("Missing values", pd.DataFrame({"A": [None, None]}))
]:
    print(label, "shape:", table.shape, "size:", table.size, "ndim:", table.ndim, "empty:", table.empty)
assert not pd.DataFrame({"A": [None, None]}).empty

Expected output

No rows shape: (0, 2) size: 0 ndim: 2 empty: True
No columns shape: (3, 0) size: 0 ndim: 2 empty: True
Missing values shape: (2, 1) size: 2 ndim: 2 empty: False

See what happens when a column becomes the index 🔝

The index is not counted as a data column or included in size. set_index() with drop=True reduces the column count. reset_index() can restore it.

indexed = students.set_index("ID")
print("Before:", students.shape, students.size)
print("After:", indexed.shape, indexed.size)
assert indexed.shape == (6, 3)
assert indexed.reset_index().shape == students.shape

Expected output

Before: (6, 4) 24
After: (6, 3) 18

Inspect dimensions after filtering and selecting columns 🔝

Each selection has its own dimensions. A preview describes only the preview; use the full table for total row counts. See head(), tail() and loc.

selected = students.loc[students["MATH"].ge(70), ["ID", "NAME", "MATH"]]
print(selected)
print("Selected shape:", selected.shape)
print("Preview shape:", selected.head(2).shape)
assert selected.shape == (4, 3)

Expected output

   ID  NAME  MATH
0   1  Ravi    80
2   3  Alex    70
3   4   Ron    70
4   5  King    70
Selected shape: (4, 3)
Preview shape: (2, 3)

Inspect a CSV after reading it 🔝

The embedded file runs without uploading anything. Replace StringIO(csv_text) with your file path or URL. Real dimensions depend on the actual file and reader options; do not assume a fixed row count. See read_csv().

csv_text = students.to_csv(index=False)
from_csv = pd.read_csv(StringIO(csv_text))
print("Rows:", from_csv.shape[0], "Columns:", from_csv.shape[1])
print("Cells:", from_csv.size, "Dimensions:", from_csv.ndim)
assert from_csv.shape == (6, 4)

Expected output

Rows: 6 Columns: 4
Cells: 24 Dimensions: 2

Inspect an Excel sheet 🔝

This in-memory workbook uses the same read_excel() call as an uploaded workbook. Excel needs an engine such as openpyxl; the example lets other cells continue if it is unavailable. See read_excel() and to_excel().

try:
    import openpyxl
except ImportError:
    print("Excel example requires openpyxl; continue with the CSV examples.")
else:
    workbook = BytesIO()
    students.to_excel(workbook, index=False, engine="openpyxl")
    workbook.seek(0)
    from_excel = pd.read_excel(workbook, engine="openpyxl")
    print("Shape:", from_excel.shape, "Size:", from_excel.size, "ndim:", from_excel.ndim)
    assert from_excel.shape == (6, 4)

Expected output

Shape: (6, 4) Size: 24 ndim: 2

Measure memory separately 🔝

memory_usage() reports memory rather than cell count. deep=True also inspects object data. The result depends on dtypes and content, so equal shapes can use different amounts of memory. See info() and dtypes.

usage = students.memory_usage(index=True, deep=True)
print("Memory bytes:", int(usage.sum()))
print("Cells:", students.size)
assert usage.sum() > 0

Expected output

Memory bytes: 593
Cells: 24

Practical example: validate the imported structure 🔝

This synthetic sales table requires three named columns and at least one row. Shape alone cannot prove that the correct fields or values were loaded. Use columns to check labels and Data Cleaning to validate values.

sales = pd.DataFrame({
    "order_id": [101, 102, 103, 104, 105],
    "product": ["Pen", "Book", "Notebook", "Bag", "Pencil"],
    "amount": ["5", "20", "bad", None, "8"]
})
required = {"order_id", "product", "amount"}
missing_columns = required - set(sales.columns)
if missing_columns:
    raise ValueError("Missing columns: " + str(sorted(missing_columns)))
if sales.shape[0] == 0:
    raise ValueError("No sales rows")
print("Imported shape:", sales.shape)
print("Required columns present:", not missing_columns)
assert sales.shape == (5, 3)

Expected output

Imported shape: (5, 3)
Required columns present: True

Reconcile accepted and review rows 🔝

Convert amounts under a defined rule and keep unknown values in review. A smaller accepted table is expected, but every source row should be accounted for. More rows do not automatically mean more valid orders.

amount = pd.to_numeric(sales["amount"], errors="coerce")
review = sales.loc[amount.isna()].copy()
accepted = sales.loc[amount.notna()].copy()
accepted["amount"] = amount.loc[accepted.index]
print("Source:", sales.shape, "Accepted:", accepted.shape, "Review:", review.shape)
print("Review IDs:", review["order_id"].tolist())
print("Known revenue:", accepted["amount"].sum())
assert accepted.shape[0] + review.shape[0] == sales.shape[0]
assert accepted["amount"].sum() == 33

Expected output

Source: (5, 3) Accepted: (3, 3) Review: (2, 3)
Review IDs: [103, 104]
Known revenue: 33.0

Export and check the row count 🔝

Export the intended table with index=False, then inspect a round-trip CSV. This verifies the selected example, but does not replace schema and dtype checks for real imports. See Input and Output.

csv_output = accepted.to_csv(index=False)
loaded = pd.read_csv(StringIO(csv_output))
print(csv_output.rstrip())
print("Reloaded shape:", loaded.shape)
assert loaded.shape == accepted.shape
assert loaded["order_id"].tolist() == [101, 102, 105]
# Optional Colab export:
# accepted.to_csv("accepted_sales.csv", index=False)

Expected output

order_id,product,amount

101,Pen,5.0

102,Book,20.0

105,Pencil,8.0
Reloaded shape: (3, 3)

Common questions 🔝

Why does shape() fail? shape is an attribute, not a function. Does size exclude missing values? No. Does len(df) count columns? It counts rows. Can a DataFrame have ndim=1? No; a selected Series has one dimension. Does a nonzero row count prove the table is usable? No; check columns, types and required values. Why did size change after indexing? Columns moved into the index are no longer counted as data cells. Practise with sample student data and NumPy arrays.

Exercise: predict dimensions after selection 🔝

Select NAME and MATH for students with Maths marks below 50. Predict shape, size and ndim, and compare the result with selecting NAME alone as a Series.

Exercise solution 🔝

Two students meet the condition. The two-column table has shape (2, 2), size 4 and ndim 2; its NAME Series has shape (2,), size 2 and ndim 1.

answer = students.loc[students["MATH"].lt(50), ["NAME", "MATH"]]
names = answer["NAME"]
print(answer)
print("Table:", answer.shape, answer.size, answer.ndim)
print("Series:", names.shape, names.size, names.ndim)
assert answer.shape == (2, 2) and answer.size == 4
assert names.shape == (2,) and names.ndim == 1

Expected output

   NAME  MATH
1  Raju    40
5  Jack    30
Table: (2, 2) 4 2
Series: (2,) 2 1

Practice in Google Colab 🔝

Open in Google Colab View on GitHub
Run the examples in order, change columns and missing values, then compare dimensions and row counts. Save your own copy to keep edits. All sample tables are included in the notebook.

Reference: Pandas DataFrame.shape documentation.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer