Data analysis with NumPy & pandas
Vectorised NumPy arrays, pandas DataFrames, filtering, groupby, pivot tables, cleaning data and merging.
Python is the most popular language for data work, thanks to two libraries: NumPy, which provides fast numeric arrays, and pandas, which builds labelled tables (DataFrames) on top of them — think "Excel and SQL, but programmable". Data analysts, data engineers, backend developers and ML engineers all use them. This lesson gives you a practical, working introduction.
NumPy: fast arrays#
A NumPy array holds many values of the same type in one contiguous block of memory. Operations apply to every element at once (vectorisation), running in optimised C instead of Python loops:
Compare with plain Python, where you'd need loops or comprehensions for each of these. Vectorised code is shorter and typically 10–100× faster on large data:
Multi-dimensional arrays
axis=0 works down the rows (per column); axis=1 works across the columns (per row). NumPy also offers random numbers (np.random.default_rng()), linear algebra (np.linalg) and statistics — it's the foundation of pandas, scikit-learn, PyTorch and most scientific Python.
pandas: DataFrames#
A DataFrame is a table with labelled columns and an index; each column is a Series. Let's create a small sales dataset as a CSV and load it:
(pandas 3 stores text columns with a dedicated str dtype; on pandas 2.x you'll see object instead.) First steps with any new dataset: head(), shape, dtypes, info() (columns, types and missing values) and describe() (summary statistics).
Selecting and filtering#
Combine conditions with & (and), | (or) and ~ (not), and wrap each condition in parentheses — Python's and/or don't work on Series. df.query("units >= 5 and city == 'Pune'") is a readable alternative.
Adding columns and aggregating#
groupby follows the split–apply–combine pattern, just like SQL's GROUP BY. Named aggregations (orders=("revenue", "size")) give you tidy column names.
A pivot table reshapes data Excel-style:
Cleaning messy data#
Real data has gaps, duplicates and inconsistent formatting. pandas has tools for each:
The duplicate "grace" row disappeared only after normalising text — the order of cleaning steps matters.
Joining tables and exporting#
pandas reads and writes many formats: read_csv/to_csv, read_excel/to_excel (needs openpyxl), read_json/to_json, read_parquet, and read_sql to load query results straight from a database connection (sqlite3 or SQLAlchemy).
Plotting (quick look)#
With matplotlib installed (pip install matplotlib), DataFrames can plot themselves:
For exploratory work, most people use Jupyter notebooks (pip install jupyterlab, then jupyter lab), which show tables and charts inline.
Performance tips#
- Vectorise: use column operations, not
forloops ordf.iterrows()— loops can be 100× slower. - Use
df["col"].map(dict)ornp.where(cond, a, b)instead of row-by-rowapplywhere possible. - Choose efficient types:
categoryfor repeated strings, and load only the columns you need withusecols=. - For data bigger than memory, read in chunks (
chunksize=) or look at Polars or DuckDB, newer libraries popular for large datasets.
Common mistakes#
- Using
and/orwith Series — use&/|with parentheses. - Chained assignment like
df[df["a"] > 1]["b"] = 9— it modifies a temporary copy, sodfis unchanged (pandas 3's copy-on-write makes this explicit with aChainedAssignmentErrorwarning). Writedf.loc[df["a"] > 1, "b"] = 9instead. - Forgetting
index=Falseinto_csv, which adds an unnamed index column. - Looping over rows instead of vectorising.
- Not parsing dates (
parse_dates=), leaving them as plain strings.
What's next#
You can now store and analyse data. Next, put your Python on the web: building web apps and APIs with Flask and FastAPI.
Check your understanding
Quick quiz
1.What does
np.array([1, 2, 3]) * 2return?2.In pandas, how do you select rows of
dfwhere thepricecolumn is above 1000?3.What does
df.groupby("city")["sales"].sum()compute?
Finished reading?
Mark this lesson complete to track your progress.