Data analysis basics: 50 cards on cleaning, pandas, SQL and A/B tests
Data analysis flashcards: summary statistics, data cleaning, joins and group-by in pandas and SQL, pivot tables, chart choices, A/B tests and causation.
Practice now
Study without an account
Scheduled with the default Askesis timings. Progress is saved in this browser.
All 50 cards
- 1Mean or median for typical household income?The median: income is right-skewed, and a few very high values pull the mean far above what a typical household earnsIn right-skewed data the mean is greater than the median. The same goes for house prices and response times.
- 2Why report p95 or p99 latency instead of the average?Averages hide the slow tail. A p95 of 800 ms means 95% of requests were faster than 800 ms and 1 in 20 users waited longer
- 3Five-number summaryMinimum, first quartile, median, third quartile and maximum: exactly what a box plot drawsBox plots usually draw points beyond 1.5 × IQR from the box as individual outliers.
- 4Get a quick statistical summary of a DataFramepython
df.describe() # count, mean, std, min, quartiles, max df.info() # dtypes, non-null counts, memorydescribe()covers numeric columns by default;describe(include="all")adds the others. - 5An outlier shows up in your data. Remove it or keep it?Investigate first. Fix or drop it if it is an error (a typo, a test record, a unit mix-up); keep it if it is real, because extreme values are often the most important dataReport results with and without it if it changes the conclusion.
- 6First checks on a new dataset in pandaspython
df = pd.read_csv("sales.csv", parse_dates=["order_date"]) df.shape df.head() df.dtypes df.isna().sum() df.duplicated().sum()Look at size, types, missing values, duplicates and value ranges before any analysis. - 7Count missing values per columnpython
df.isna().sum()df.isna().mean()gives the share of missing values instead. - 8Options for handling missing valuesDrop the rows or columns, fill them (median, mode, a constant, or forward-fill for time series), or keep them and add an “is missing” flag. The right choice depends on why they are missingIf missingness is related to the value itself, such as high earners skipping an income question, dropping or mean-filling biases the results.
- 9Remove duplicate orders, keeping the latest versionpython
df = df.drop_duplicates(subset=["order_id"], keep="last")Withoutsubset, only rows that are identical in every column count as duplicates. - 10Convert a text column with stray values to numberspython
df["price"] = pd.to_numeric(df["price"], errors="coerce")errors="coerce"turns values it can’t parse, such as "N/A" or "12,50", into NaN, so count the new NaNs afterwards. - 11Parse a date column and extract the monthpython
df["created_at"] = pd.to_datetime(df["created_at"]) df["month"] = df["created_at"].dt.monthThe.dtaccessor also offersyear,day_name(),to_period("M")and more. - 12Clean inconsistent category labels like "USA", " usa" and "U.S."python
df["country"] = ( df["country"].str.strip().str.upper() .replace({"U.S.": "USA", "UNITED STATES": "USA"}) )Check the result withvalue_counts(). - 13Filter rows on two conditions in pandaspython
df[(df["country"] == "DE") & (df["amount"] > 100)]Use&,|and~with parentheses around each condition; Python’sandandorraise an error on Series. - 14
locvsiloclocselects by labels and boolean masks;ilocselects by integer positionLabel slices withlocinclude the end label;ilocslices exclude the end, like Python lists. - 15Add a revenue column from price and quantitypython
df["revenue"] = df["price"] * df["qty"]Vectorized column arithmetic is much faster than looping over rows or callingapplyrow by row. - 16Top 10 rows by revenuepython
df.sort_values("revenue", ascending=False).head(10)df.nlargest(10, "revenue")does the same. - 17Count how often each value occurs in a columnpython
df["status"].value_counts()Addnormalize=Truefor proportions anddropna=Falseto count missing values too. - 18Why write
df.loc[mask, "col"] = valueinstead ofdf[mask]["col"] = value?The chained version may assign to a temporary copy and leavedfunchanged; a singleloccall always updates the originalWith Copy-on-Write, the default from pandas 3.0, chained assignment never updates the original. - 19Total revenue per week from daily orderspython
df.set_index("order_date").resample("W")["amount"].sum()Use"MS"for calendar months starting on the 1st or"ME"for month end; the old"M"alias is deprecated in recent pandas. - 20Total revenue per region in pandaspython
df.groupby("region")["revenue"].sum()Group-by follows split-apply-combine: split rows into groups, apply a function to each, combine the results. - 21Several named aggregations per group in pandaspython
df.groupby("region").agg( orders=("order_id", "nunique"), revenue=("amount", "sum"), avg_order=("amount", "mean"), ) - 22Join customer details onto orders in pandaspython
orders.merge(customers, on="customer_id", how="left")Useleft_onandright_onwhen the key columns have different names. - 23Inner vs left vs outer joinInner keeps only rows whose key appears in both tables; left keeps every row of the left table, with missing values where there is no match; outer keeps every row from both
- 24After a left join you have more rows than before. Why?The key isn’t unique in the right table, so each left row is repeated once per match, which also inflates any sumsCatch it early with
merge(..., validate="many_to_one"), which raises an error if the right-hand keys repeat. - 25Find orders whose customer is missing from the customers tablepython
m = orders.merge(customers, on="customer_id", how="left", indicator=True) m[m["_merge"] == "left_only"]In SQL:LEFT JOINand keep rows where the right table’s keyIS NULL. - 26What does a pivot table do?Summarizes data by turning the values of one column into rows and another into columns, with an aggregate such as a sum at each intersectionExample: revenue by region (rows) and month (columns).
- 27Revenue by region and month as a pivot table in pandaspython
df.pivot_table(index="region", columns="month", values="revenue", aggfunc="sum", fill_value=0)The defaultaggfuncis the mean, so set it explicitly.margins=Trueadds totals. - 28
pivotvspivot_tablein pandaspivotonly reshapes and fails if an index/column pair appears more than once;pivot_tableaggregates the duplicates - 29Reshape monthly columns (wide) into rows (long)python
df.melt(id_vars=["region"], var_name="month", value_name="revenue")Long, or tidy, data has one row per observation and one column per variable, which most plotting and group-by tools expect. - 30Orders and revenue per region in SQL, biggest firstsql
SELECT region, COUNT(*) AS orders, SUM(amount) AS revenue FROM orders GROUP BY region ORDER BY revenue DESC; - 31Pivot statuses into columns in SQLsql
SELECT region, SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS paid, SUM(CASE WHEN status = 'refunded' THEN amount ELSE 0 END) AS refunded FROM orders GROUP BY region;PostgreSQL also supportsSUM(amount) FILTER (WHERE status = 'paid'). - 32Monthly revenue in PostgreSQLsql
SELECT DATE_TRUNC('month', created_at) AS month, SUM(amount) AS revenue FROM orders GROUP BY 1 ORDER BY 1;BigQuery puts the unit second, as inDATE_TRUNC(order_date, MONTH); MySQL has noDATE_TRUNC, so useDATE_FORMAT(created_at, '%Y-%m-01'). - 33Each region’s share of total revenue in SQLsql
SELECT region, 100.0 * SUM(amount) / SUM(SUM(amount)) OVER () AS pct_of_total FROM orders GROUP BY region;The window function runs afterGROUP BY, so it can sum the per-region sums. - 34Why might
SELECT converted / visitorsreturn 0?Both columns are integers, and in PostgreSQL, SQL Server and SQLite integer division truncates. Multiply by1.0or cast to a decimal firstsqlSELECT 1.0 * converted / visitors AS conversion_rate FROM funnel; - 35Daily active users from an events tablesql
SELECT event_date, COUNT(DISTINCT user_id) AS dau FROM events GROUP BY event_date;COUNT(*)would count events, not people. - 36Best chart to compare a value across categoriesA bar chart, sorted by value, with the axis starting at zeroUse horizontal bars when the category names are long.
- 37Best chart to show a trend over timeA line chart, with time on the x-axis
- 38Best chart to show the distribution of one numeric variableA histogram, or a box plot when comparing distributions across groupsTry several bin widths: too few bins hide the shape, too many add noise.
- 39Best chart to show the relationship between two numeric variablesA scatter plot, optionally with a trend lineWith many points, use transparency or a 2D histogram so dense areas stay readable.
- 40Why avoid a pie chart with many slices?People compare angles and areas poorly; beyond a few categories, a sorted bar chart shows the differences far more clearly
- 41Why should a bar chart’s value axis start at zero?Bar length encodes the value, so a truncated axis makes small differences look hugeLine charts may use a non-zero baseline, because they show change, not size.
- 42A/B testA randomized experiment: users are randomly assigned to a control (A) or a variant (B), and a predefined metric is compared between the groupsRandom assignment makes the groups alike on average in everything except the change, so a difference in the metric can be attributed to it.
- 43What should you decide before starting an A/B test?The primary metric, the minimum effect worth detecting, the sample size (from a power analysis), the duration and the rule for stopping
- 44The peeking problemChecking results repeatedly and stopping as soon as p < 0.05 greatly inflates the false-positive rate. Fix the sample size in advance or use a sequential testing method
- 45Statistical vs practical significanceWith a huge sample, a tiny effect can be statistically significant yet too small to matter; look at the effect size and its confidence interval, not just the p-value
- 46Sample ratio mismatch (SRM)The groups’ sizes differ from the planned split, such as 50.0/50.0 planned but 51.5/48.5 observed with 100,000 users. It signals an assignment or logging bug, so don’t trust the results until it’s explainedA chi-square test on the group counts detects it.
- 47Ice cream sales and drownings rise together. Does ice cream cause drowning?No. Hot weather drives both: it is a confounding variableA confounder influences both the supposed cause and the effect, creating an association without causation.
- 48Simpson’s paradoxA trend that holds within every group reverses or disappears when the groups are combined, because the groups differ in size or mixA classic study found treatment A had higher success rates for both small and large kidney stones, yet B looked better overall, because A was used far more on the harder, large stones.
- 49Survivorship biasDrawing conclusions only from cases that made it through a filter, such as studying successful startups or customers who stayed, while ignoring those that failed or leftWWII analysts were advised to armor the areas where returning bombers had no bullet holes: planes hit there never made it back.
- 50Pearson r ≈ 0. Does that mean no relationship?No, only no linear relationship. A U-shaped pattern can have r near 0, so always plot the dataSpearman’s rank correlation captures any monotonic relationship and is less sensitive to outliers.
Frequently asked questions
Do I need to know Python?
Basic Python helps with the pandas cards. The SQL, charting, A/B testing and causation cards need no Python at all.
How is this different from the Statistics deck?
The Statistics deck covers formulas and theory such as distributions, hypothesis tests and regression. This deck is about applying them to real, messy data: cleaning, joining, reshaping, charting and reading experiments.
Which SQL dialect is used?
PostgreSQL, a common choice for analytics. Cards point out where MySQL, BigQuery or SQLite behave differently.
Is it useful for data analyst interviews?
Yes. Joins that duplicate rows, group-by and pivot questions, chart choices, A/B test pitfalls and correlation vs causation come up constantly in analyst interviews.
More in Data & AI
Machine learning
Machine learning flashcards: supervised vs unsupervised learning, overfitting, bias-variance, regularization, gradient descent, common models and metrics.
50 cardsPrompt engineering
Prompt engineering flashcards: tokens, context windows, temperature, few-shot and chain-of-thought prompting, structured output, RAG and prompt injection.
50 cards