Act I · One variable
Annual earnings for 171 full-time working women aged 30. A column of 171 dollar amounts tells you nothing at a glance.
Univariate summary is how we compress that column into a handful of numbers — and a few pictures — that reveal its center, its spread, and its shape.
For skewed economic data, the median is usually the more honest “typical” value.
Act II · The investigation
import pandas as pd # tabular data
from scipy import stats # skewness & kurtosis
# dataset: 171 full-time working women aged 30, 2010 (earnings in $)
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_EARNINGS.DTA"
data = pd.read_stata(url) # read the Stata .dta into a DataFrame
data[["earnings"]].describe().round(0) # count, mean, std, min, quartiles, max
stats.skew(data["earnings"]), stats.kurtosis(data["earnings"]) # shape: 1.71, 4.32 (excess)A handful of high earners (max $172,000) drag the mean up; report the median as “typical.”
Box = \(Q_1\) to \(Q_3\) (the middle 50%); red line = median; dots on the right = high-earner outliers.
The median sits left of center and the right whisker is long — the chart is the skew.
import pandas as pd # tabular data
import matplotlib.pyplot as plt # plotting
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_EARNINGS.DTA"
earnings = pd.read_stata(url)["earnings"] # the single variable
fig, ax = plt.subplots(1, 2, figsize=(12, 5)) # two panels side by side
ax[0].hist(earnings, bins=12, color="#22d3ee", edgecolor="black") # wider bins → coarse shape
ax[1].hist(earnings, bins=25, color="#22d3ee", edgecolor="black") # narrower bins → fine detail
plt.show() # render the histogramsThe same 171 earnings at two bin widths. Both show the long right tail; the narrower bins reveal clustering around $25k–$45k.
Always try more than one bin width — each answers a different question.
U.S. health spending, 2018: hospital care alone is ~1/3 of $3,653B — more than physicians and drugs combined.
Sort categories before plotting so the ranking reads instantly.
import pandas as pd # tabular data
import matplotlib.pyplot as plt # plotting
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_FISHING.DTA"
data = pd.read_stata(url) # 1,182 recreational fishers
counts = data["mode"].value_counts() # frequency of each fishing site
counts / counts.sum() * 100 # relative frequency (% of total)
plt.pie(counts, labels=counts.index, autopct="%1.1f%%") # each slice = a site's share
plt.show() # render the pie chartCharter (38.2%) + private (35.4%) = 74% of fishers choose a boat; pier and beach split the rest.
Pie charts show shares; for many categories a sorted bar chart compares them more cleanly.
import numpy as np # natural logarithm
import pandas as pd # tabular data
from scipy import stats # skewness
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_EARNINGS.DTA"
data = pd.read_stata(url) # load the 171 earnings
data["ln_earnings"] = np.log(data["earnings"]) # log-transform the skewed variable
stats.skew(data["earnings"]) # 1.71 → strong right skew
stats.skew(data["ln_earnings"]) # -0.91 → nearly symmetricPanel A: earnings in dollars, strongly right-skewed. Panel B: log(earnings), roughly symmetric — skew falls from 1.71 to −0.91.
Many tests assume a bell shape; the log transform is how skewed economic data gets there.
import pandas as pd # tabular data
url = "https://raw.githubusercontent.com/quarcs-lab/data-open/master/AED/AED_MONTHLYHOMESALES.DTA"
data = pd.read_stata(url).query("year >= 2005") # monthly U.S. home sales, 2005+
data = data.sort_values("daten") # ensure time order
data["ma11"] = data["exsales"].rolling(11, center=True).mean() # 11-month moving average
data[["exsales", "ma11"]].describe().round(0) # raw (noisy) vs smoothed seriesRaw monthly sales zig-zag with the seasons; the 11-month moving average (red) and seasonal adjustment (green) expose the boom–bust–recovery cycle.
A moving average cancels seasonal noise; seasonal adjustment removes the predictable pattern itself.
Act III · The resolution
Objection. “Just report the mean and a histogram — that’s what a summary is.”
Response. The right summary depends on the shape. For skewed earnings, the mean overstates the “typical” value, so lead with the median and IQR. A histogram’s story changes with its bin width. And a raw time series hides its trend until you smooth it.
Match the tool to the data: skew → median & logs; categories → bars; time → moving averages.