Introduction to Business Analytics — HKUST
Why it matters
“Coding is not just for tech people — it is for anyone who wants to run a competitive company in the 21st century.”
— Mary Callahan Erdoes, JPMorgan
Data Science Language Popularity 2025
| Language | Share |
|---|---|
| Python | 31% |
| JavaScript | 24% |
| Java | 17% |
| R | 12% |
| SQL | 8% |
Course workflow:
🐍 Python Essentials → 📋 Data Processing → 📈 Linear Regression → 🧩 Clustering
| Topic 1 | Topic 2 | Topic 3 | Topic 4 |
|---|---|---|---|
| Python Essentials | Data Processing | Linear Regression | Clustering |
Key takeaway
Today (Topic 1): Lists, NumPy arrays, and pandas Series — the three containers you will use every day.
pippd, np, plt)Core libraries
pipWhy it matters
Python comes with basics, but for data analysis we need extra toolboxes (packages). Think of pip as an app store for Python.
A module is like a toolbox — you import the tools you need.
append, remove, len, sortstock_tickers
| [0] | [1] | [2] | [3] |
|---|---|---|---|
| AAPL | GOOG | TSLA | NVDA |
.append() — add.remove() — delete.sort() — orderA list stores an ordered collection of items — numbers, strings, anything.
Why it matters
In business, lists represent portfolios, product catalogs, customer IDs, and survey responses.
Business Use Cases
Python counts from 0 (zero-indexed). Negative indices count from the end.
| index 0 | index 1 | index 2 | index 3 |
|---|---|---|---|
| AAPL | GOOG | TSLA | NVDA |
| -4 | -3 | -2 | -1 |
Key takeaway
.append() adds, .remove() deletes, len() counts, .sort() orders (use reverse=True for descending).
Try it!
Given monthly sales figures:
sales = [12000, 15000, 8000, 22000, 18000, 9000]
25000 as next month’s salesFor-loop: 4 lines of code
vs.
Comprehension: 1 line
[expr for item in list][expr for item if cond][A if c else B for item]Business problem: Apply a 10% price increase to all products.
Key takeaway
Pattern: [expression for item in list]
Business problem: Show only premium products (price > 150).
Key takeaway
Pattern: [expression for item in list if condition]
The output list can be shorter than the input — items are filtered out.
Business problem: Generate Buy/Sell signals based on price.
Key takeaway
Pattern: [A if cond else B for item in list]
Output always has the same length as input — every item gets a value.
Try it!
Classify exam scores: scores = [88, 45, 72, 95, 61]
Output "Pass" if score \(\geq\) 60, else "Fail".
Business problem: Assign letter grades based on score thresholds.
Key takeaway
You can chain if/else inside a comprehension. Read left to right: first condition checked first.
Important
Avoid nesting more than 2–3 conditions — beyond that, use a helper function for readability.
.dtype, .shape, .index, .name📋 List (no math, no stats, no plots)
⬇ pd.Series(list)
📊 pd.Series (math ✓ stats ✓ plots ✓)
Why it matters
Lists are general-purpose containers. For data analysis — math, statistics, plotting — we need something more powerful.
List vs. pd.Series
| Operation | List | Series |
|---|---|---|
prices + 10 |
✗ | ✓ |
.mean() |
✗ | ✓ |
.max() |
✗ | ✓ |
.plot() |
✗ | ✓ |
Key takeaway
pd.Series(list) converts a plain list into a powerful data object with built-in math, statistics, and plotting.
List → Series
| List | Series (with index) | |
|---|---|---|
| 100 | → | Mon : 100 |
| 102 | → | Tue : 102 |
| 98 | → | Wed : 98 |
| 105 | → | Thu : 105 |
| 101 | → | Fri : 101 |
Attributes (no parentheses)
Describe the data: .dtype, .shape, .index, .name
Methods (with parentheses)
Compute on the data: .mean(), .max(), .plot()
.value_counts() and .sort_values().describe() — full summary.value_counts() — categories.sort_values() — rank.plot() / .hist() — visualizeCentral tendency (typical value):
.mean() — numerical, outlier-affected.median() — numerical, robust.mode() — categorical & numericalVariation:
.std() — standard deviation.quantile(.75) - .quantile(.25)import isom2600
aapl = isom2600.data.getStock("AAPL")["Close"].squeeze().squeeze()
print(aapl.mean()) # Average price
print(aapl.median()) # Median price
print(aapl.std()) # Volatility (sample std)
print(aapl.min()) # Lowest price
print(aapl.max()) # Highest price
# Interquartile range
iqr = aapl.quantile(0.75) - aapl.quantile(0.25)
print(aapl.describe()) # Full summary in one call!Why it matters
.describe() gives you count, mean, std, min, 25%, 50%, 75%, max — the complete “profile” of your data in one line.
.value_counts() and .sort_values()import isom2600
aapl = isom2600.data.getStock("AAPL")["Close"].squeeze()
# .squeeze() converts a one-column DataFrame to a Series
aapl.plot() # Line chart (default)
aapl.hist(bins=30) # Histogram
aapl.plot(kind="bar") # Bar chartKey takeaway
pandas integrates with matplotlib. One method call = one chart. Customize with figsize, color, title.
Conceptual line chart: AAPL price trending upward over days. One line of code: aapl.plot().
Broadcasting: array * 2
| Input | 1 | 2 | 3 |
|---|---|---|---|
| × 2 | 2 | 4 | 6 |
List *2 would repeat the list instead!
Key takeaway
NumPy arrays support element-wise math (broadcasting), just like pd.Series — but without a named index.
List ×2 ✗ → repeats list
[100,102,...,100,102,...]
Array ×2 ✓ → each doubled
[200,204,196,210,202]
Syntax: np.random.normal(μ, σ, n) — draw n samples from \(\mathcal{N}(\mu,\,\sigma^2)\)
Key takeaway
Each call gives different random draws. The sample mean/std will be close to \(\mu\)/\(\sigma\) but not exact.
matplotlibplt.subplots()plt vs. Series MethodsKey takeaway
Use Series methods for quick exploration. Use plt when you need full control or non-pandas data.
Key takeaway
Key params: color, linewidth, linestyle, marker, label.
Why it matters
Histograms reveal shape: is the return symmetric? Are there fat tails?
Key takeaway
Scatter plots reveal the direction and strength of association between two variables.
Key takeaway
plt.subplots(r, c) returns a grid of Axes objects. Always call plt.tight_layout() to prevent overlap.
import isom2600
import pandas as pd
import matplotlib.pyplot as plt
aapl = isom2600.data.getStock("AAPL")["Close"].squeeze()
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
aapl.plot(ax=axes[0], title="Price", color="steelblue")
aapl.hist(ax=axes[1], bins=25, color="coral")
axes[1].set_title("Distribution")
stats_s = pd.Series({"Mean": aapl.mean(),
"Median": aapl.median(), "Std": aapl.std()})
stats_s.plot(kind="bar", ax=axes[2], color="seagreen")
plt.tight_layout(); plt.show()Key takeaway
Series methods (.plot(), .hist()) accept ax= to place them in subplots. No need to pass x and y separately.
Try it!
np.random.normal(0.001, 0.02, 300). Plot the histogram. Add a vertical dashed line at the mean.plt.tight_layout().CDF: value → probability
Given \(x=10\), the shaded area under the normal density to the left of 10 = 84.1%.
PPF: probability → value
Given probability 5%, the \(x\)-value that cuts off the left 5% of the distribution is \(x = 4.71\).
Key takeaway
.cdf(x): value → probability \(\longleftrightarrow\) .ppf(p): probability → value
Normal density with the left-tail 5% region shaded — the VaR is the cutoff \(x\) such that \(P(X < \text{VaR}) = 5\%\).
Key takeaway
VaR: “Worst outcome at 95% confidence.” Standard in risk management.
Build a Portfolio Analyzer using everything you learned today.
Key takeaway
This mini project combines lists, comprehensions, f-strings, pd.Series, and matplotlib — all in one workflow.
| Property | List | pd.Series | np.array |
|---|---|---|---|
| Mixed types | ✓ | ✗ | ✗ |
| Element-wise math | ✗ | ✓ | ✓ |
| Built-in stats | ✗ | ✓ | ✓ |
| Named index | ✗ | ✓ | ✗ |
| One-liner plots | ✗ | ✓ | ✗ |
| Fastest math | ✗ | ✗ | ✓ |
Key takeaway
Rule of thumb: Start with a list for raw data. Convert to pd.Series for analysis. In this course, we mostly use pd.Series for data work. We only use np.array for generating random samples (e.g., np.random.normal()).
Prof. Xuhu Wan · HKUST ISOM · Intro to Business Analytics