Data scientist interviews test whether you can turn a vague business question into something you can measure, model and defend. Expect a project deep-dive, questions on cleaning data and building features, metric choices such as precision against recall, experiment design, a short SQL or pandas task, a product case, and stories about explaining results to people who don't read code. Each question shows what the interviewer is really checking, a shape for your answer and a sample you could say out loud. Algorithm internals and pure statistics have their own pages, so this one stays close to the day-to-day job.
Search all questions by round, difficulty and level, or save the ones you want to practise.
Starting point: the study, job or project that first pulled you towards data.
Turning point: one piece of work where you saw data change a real decision.
Next: the kind of problems you want now and why this role offers them.
"I studied economics, and the part I kept enjoying was the empirical work, cleaning a messy dataset and seeing whether the story held up. My first job was as an analyst in a retail team, mostly SQL and dashboards. The turning point was when I built a simple model to predict which stores would run out of stock, and the operations team actually changed their reorder schedule because of it. That's when I realised I wanted to build things that change decisions, not just report on them. Since then I've learned Python properly and shipped two models. Next, I want problems close to the product, like retention or pricing, where I can run experiments and see the effect."
Saying you got into data science because it's a well-paid, popular field, with no example of work you enjoyed.
The difference: analysts explain what happened, ML engineers make models run reliably at scale, data scientists sit between.
Your fit: the parts of the work you enjoy most and are best at.
Honest overlap: what you'd still borrow from the other two roles.
"The way I see it, an analyst mostly answers what happened and why, an ML engineer makes sure a model runs reliably in production, and a data scientist spends more time on the question in between: what will happen, and what should we do about it. That middle part is what I enjoy. I like framing a fuzzy problem, testing whether a model or an experiment can answer it, and then explaining the result. I still want the analyst's habit of checking numbers against reality, and enough engineering skill that my code doesn't have to be rewritten before it ships. But my strongest work has been in that framing and modelling space, so this role fits best."
Describing the analyst role as beneath you, or not being able to say what an ML engineer does.
How they make money: the core loop, such as acquisition, conversion, retention.
One decision: a recurring decision that data could improve.
Humility: what you'd check first before committing to it.
"From the outside, it looks like your revenue depends on subscribers staying past the first couple of months, so retention seems like the biggest lever. If I were starting, I'd want to understand what separates people who stay from people who leave in those early weeks, and whether there's a decision the team makes every week that could use that, like which users get onboarding help or which get an offer. I'd probably start with a careful analysis before any model, because a clear picture of where people drop off might be enough on its own. That said, I'm guessing from public information, so the first thing I'd do is ask the team which decisions they feel least confident about."
Proposing a fashionable model with no link to how the business makes money or which decision it would change.
Risk vs response: a high churn score doesn't mean the discount changes their mind.
Wasted and harmful sends: some would stay anyway, some are lost causes, some may be pushed to leave by the contact.
Fix: hold out a random control group, then consider an uplift approach.
"My main warning would be that the model predicts who's likely to leave, not who the discount will save. Some of those high-risk customers have already decided, and no offer will keep them. Others on the list might have stayed anyway, so we'd be giving away margin for nothing. And contacting some people can remind them to cancel. So I'd ask marketing to keep a random slice of the high-risk group as a control that gets no discount. Comparing the two tells us whether the offer actually reduces churn. If it works for some kinds of customers and not others, the next step is an uplift model that targets the people most likely to change their behaviour because of the offer."
Saying the model's top list is automatically the right target for the discount.
Is it real: check logging, pipeline delays and any change to how the metric is defined.
Where: split by platform, app version, country, new versus returning users and traffic source.
Why: line it up with releases, outages, marketing changes, holidays and outside events.
"First I'd check whether the drop is real. Did yesterday's data fully arrive, did any tracking change in a recent release, and is the metric definition the same? A surprising number of sharp drops are logging problems. If it's real, I'd split it: by platform and app version, by country, by new against returning users, and by traffic source. A drop concentrated in one slice, say Android users on the latest version, points straight to a cause. Then I'd line up the timing, hour by hour, against releases, outages, changes in marketing spend and outside events like a public holiday. I'd share a quick first read within hours, saying what's ruled out and what's still open."
Jumping to a product explanation without first checking whether the data itself is broken.
Goal: the user problem it solves and how that should show up in behaviour.
Metrics: one primary metric tied to the goal, usage metrics that show adoption, and guardrails that catch harm.
Cause: an A/B test, because engaged users use every feature and buy more anyway.
"I'd start with why we're building it. Presumably people find things they like but aren't ready to buy, and we lose them. So success means more of those people come back and buy. My primary metric would be purchases per user over a few weeks, because that's the business goal. Supporting metrics show whether it's used: how many people save items, and how many saved items are bought later. I'd add a guardrail, because a save button could let people park items instead of buying now, so I'd watch same-session conversion too. And I wouldn't just compare people who save with people who don't, since keen shoppers use every feature and buy more anyway. I'd run an A/B test and compare the two groups over the same weeks."
Calling it a success because lots of people clicked the button, or comparing savers with non-savers and calling the gap the effect.
Question: who needed what, and what decision it fed.
Data and approach: where the data came from, the key cleaning and modelling choices, and why.
Validation: how you knew it worked before and after launch.
Result: what changed, and what you'd do differently.
"At my last company the support team wanted to know which new tickets were likely to escalate, so senior agents could pick them up early. I pulled a year of tickets, and the tricky part was the label, because escalation was logged in two different ways across systems, so I spent the first week agreeing a definition with the support lead. I built features from the ticket text, the customer's history and the product area, and started with logistic regression as a baseline before trying gradient boosting, which did clearly better. I validated on the most recent two months rather than a random split. We ran it on a subset of queues first, and escalated tickets were picked up much sooner. Looking back, I'd have involved the agents earlier in the feature ideas."
Only describing the algorithm, or not knowing why a choice was made because a teammate or tutorial made it.
The ask: the original request, word for word if you can.
Clarifying: the questions you asked and what decision the answer fed.
Breakdown: how you split it into hypotheses you could test.
Result: what you found and how it was used.
"A director once asked me to find out why online sales were down. Before opening any data, I asked down compared with what, since when, and what she'd do with the answer. It turned out she meant the last month against the same month last year, and she was deciding whether to increase ad spend. I split sales into visitors, conversion rate and order value, and checked each by channel and device. Visitors and order value were fine; conversion had dropped, almost entirely on mobile, starting the week of a site release. I shared that within two days, the engineers found a broken payment step on some phones, and the ad budget stayed where it was."
Diving straight into a model or a big dashboard without asking what the question really was.
Decision: what the team will do differently with a prediction, and for whom.
Definition: what counts as churn, over what window, predicted how far ahead.
Success: how we'll know the model helped, not just scored well.
"First, I'd ask what they'll do with the prediction, because a list for a retention team making calls needs something different from a score that triggers an automatic email. Then I'd pin down what churn means here: cancelling a subscription, or just not using the product for a set number of days? And how far ahead do we need to know, since predicting a week ahead leaves less room to act than a month ahead. I'd ask how many customers the team can actually act on each week, which tells me whether precision at the top of the list matters most. Finally, I'd ask how we'll measure success, ideally with a holdout group, so we know the action saved customers."
Jumping to which algorithm you'd use before asking what churn means or what the team will do with it.
The gap: the offline number against what happened live.
Diagnosis: how you found the cause, step by step.
Fix: what you changed in the model and in the process so it wouldn't repeat.
"I built a model to rank leads for a sales team, and offline it separated good and bad leads very well. Two weeks after launch the sales team said the rankings felt random. I compared the live feature values with the training data and found the problem: one strong feature, days since the last website visit, was computed from a nightly snapshot in training but in real time in production, so the distributions didn't match at all. The model had learned patterns that didn't exist live. I moved both paths onto the same feature code, retrained, and ran the new version in shadow mode for two weeks before switching over. Since then, I always compare training and live feature distributions before calling a launch done."
Blaming the users or the engineers, or saying none of your models has ever underperformed.
The options: the two models and how far apart they really were.
What mattered: latency, explainability, maintenance, data needs or regulation.
Outcome: how the simpler choice played out.
"For a credit limit project, a gradient boosted model beat our logistic regression by a small margin on the validation set, about one point of AUC. But the risk team had to explain every decision to customers and auditors, the model had to run inside an old system with tight response times, and the boosted version needed three extra data feeds that failed now and then. I laid those trade-offs out in one page and recommended the logistic regression, with the boosted model kept as a benchmark. It went live faster, the risk team could read every coefficient, and when one feed broke months later, our model wasn't affected. The small accuracy gain wasn't worth that fragility."
Treating the leaderboard score as the only thing that matters.
Confirm: measure live performance on recent labelled data against the launch baseline.
Diagnose: check input distributions, pipeline changes and shifts in the business.
Act: fix broken inputs, retrain on recent data, or rethink features, then set up monitoring.
"First I'd confirm it with numbers, comparing the model's performance on the most recent labelled data with what we saw at launch, keeping in mind labels may arrive late. Then I'd check whether the inputs have moved: compare the distribution of each important feature now against the training data, and check whether an upstream table changed its definition or started arriving with gaps. If the pipeline is fine and the world has changed, say new customer segments or a pricing change, I'd retrain on recent data and check whether some features have stopped being useful. After that, I'd put alerts on feature drift and prediction drift, and agree a retraining schedule, so we catch it in weeks rather than months."
Retraining on new data straight away without checking whether an input pipeline broke.
Definition: the model sees information during training that it won't have when it's used for real.
Subtle examples: future-dated features, preprocessing fitted on all data, the same entity in train and test.
Defence: time-aware splits, pipelines, and suspicion of features that look too good.
"Leakage is when the model learns from information it won't have at prediction time, so validation scores look great and live performance collapses. The obvious case is a column that's basically the answer. The sneaky ones are more common. For example, predicting loan default with a 'number of collection calls' field, which only fills up after a borrower has already started missing payments. Another is scaling or target-encoding on the full dataset before splitting, so test information seeps into training. And if the same customer appears in both train and test with slightly different rows, the model memorises them. My defences are splitting by time or by entity, putting all preprocessing inside a pipeline, and investigating any feature that's suspiciously strong."
Only describing the obvious case of the target column being included by mistake.
Signs: strong training scores, much weaker validation scores, a gap that widens as the model gets more complex.
Fixes: more data, simpler model, regularisation, fewer or better features, early stopping.
Honest testing: choose settings with cross-validation and keep a final test set untouched.
"The main sign is a big gap between how the model does on training data and on data it hasn't seen. If training accuracy keeps rising while validation accuracy flattens or drops as I add depth or features, it's memorising noise. Learning curves help here. To fix it, I'd first try a simpler model or stronger regularisation, like limiting tree depth or adding a penalty on the weights. Removing noisy or redundant features helps, and so does more data if it's available. For boosting or neural nets, early stopping on a validation set is simple and effective. And I choose those settings using cross-validation, keeping a final test set I only look at once, so I don't overfit to my own validation set."
Saying you'd judge overfitting by training accuracy alone, or that more complex models are always better.
Mirror real use: train on the past and test on the period right after it, the way the model will run.
Several cut-offs: repeat with cut-off dates spread through the year so one unusual period doesn't decide the model.
Only real data: each test period sees only data that would exist at forecast time; hold out whole stores if new stores matter.
Final check: keep the most recent period untouched until the model is chosen.
"Random k-fold shuffles the weeks, so the model trains on later weeks and gets tested on earlier ones. That leaks the future, like knowing about a holiday spike before it happens, and the scores look better than they'll ever be live. Instead I'd copy how the model will actually be used: train on everything up to a cut-off date and test on the week or few weeks after it. I'd repeat that with several cut-offs spread through the year, so one lucky or unusual period doesn't pick the model for me. If features use recent sales, I'd make sure each test period only sees data that would really exist when the forecast is made. If we'll need forecasts for new stores, I'd also hold out whole stores. And I'd keep the latest period aside for one final check."
Using shuffled k-fold on time-ordered data and quoting that score as what to expect live.
Metrics first: accuracy is meaningless here; use precision, recall, PR-AUC, and precision at the top of the list.
Training options: class weights, resampling on training folds only, more positive examples if possible.
Threshold: pick it from business costs, not the default of 0.5.
"First, I'd drop accuracy, because predicting 'negative' every time already gets it almost perfect. I'd look at precision and recall, PR-AUC, and how many true positives land in the top slice the team can actually review. I'd use stratified splits, or time-based splits if time matters, so every fold has positives. For training, class weights are my first choice because they're simple and don't change the data. If I try oversampling or undersampling, I only do it on the training folds, never on the validation or test data, or the scores become fiction. Finally, the default threshold of 0.5 is rarely right, so I'd choose the cut-off with the business based on what a missed case and a false alarm each cost."
Reporting high accuracy as success, or oversampling before splitting the data.
The error: what was wrong and how you found it.
Speed: who you told, and how quickly.
Correction: the fixed result and what it changed.
Prevention: the check you added afterwards.
"I once sent a revenue analysis to a regional manager showing one product line growing much faster than the others. A few days later, while reusing the query, I noticed a join to a promotions table was duplicating orders that had more than one promotion attached. The growth was partly fake. I told my manager the same morning, then emailed the regional manager with the corrected numbers and a plain explanation of what went wrong. The product line was still growing, just more slowly, so the decision didn't flip, but it could have. Since then I check row counts before and after every join and compare totals against a known source before anything leaves my hands."
Quietly fixing the numbers without telling anyone who had already used them.
Structure: what one row represents, the columns, their types and the time range.
Quality: missing values, duplicates, impossible values and outliers.
Patterns: distributions, the target, relationships and trends over time, tied to the question.
"I start by working out what one row represents, because a table of orders and a table of order lines lead to very different mistakes. Then I check the size, column types and the date range, and whether totals roughly match a number I trust, like last month's revenue from finance. Next come quality checks: missing values by column, duplicate keys, values that can't be right like negative ages, and extreme outliers. After that I look at distributions of the important columns and the target, and how things change over time, since a sudden jump often means a logging change. Throughout, I keep the business question in front of me and write down anything odd to ask the data owner."
Jumping straight into modelling, or listing chart types with no link to the question.
Why it's missing: at random, linked to other columns, or linked to the missing value itself.
Options: drop rows or columns, simple fills, model-based fills, or a missing flag.
Leakage: learn fill values from training data only, inside the pipeline.
"First I look at how much is missing and why. If a column is mostly empty, I might drop it. If it's missing purely by chance, a median or most-frequent fill can be fine. But often missingness means something, like income left blank more often by certain applicants, so I add a flag column saying the value was missing, and the model can learn from that. For important features, I might use a model-based fill based on other columns. Some gradient boosting libraries handle missing values directly, which is handy. Whatever I choose, I fit the fill values on the training data only and apply them to validation and test data, so nothing leaks from the evaluation set."
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegression
model = make_pipeline(
SimpleImputer(strategy="median", add_indicator=True),
LogisticRegression(max_iter=1000),
)
model.fit(X_train, y_train) # fill values learned from training data only
Filling every gap with the mean of the full dataset before splitting, without asking why it's missing.
Setup: pick a snapshot date; features use only data before it, the label comes from the month after.
Feature families: usage and its trend, tenure and plan, billing issues, support contacts.
Checks: test which features really help and guard against leakage.
"I'd start with the setup: choose snapshot dates, build every feature from data before that date, and label whether the subscriber cancelled in the following month. Then feature families. Usage: logins, sessions, key actions in the last 7 and 30 days, and the trend, like this month against last month, because a decline often matters more than the level. Account: tenure, plan type, price changes, discounts ending soon. Billing: failed payments or an expiring card. Support: number of tickets and complaints recently. I'd also think about the product, like whether they've set up the feature that usually makes people stick. Then I'd check which families actually improve validation performance and look hard at any feature that seems too good to be true."
Building features from the whole customer history, including activity after the prediction date.
Audience: who they were and what decision they owned.
Translation: how you turned the output into their terms, with an example.
Check: how you knew they understood and what they did with it.
"I built a model predicting which customers were likely to stop ordering, and I had to present it to the head of customer success. I skipped the AUC entirely. Instead, I said: if your team calls the 200 customers the model ranks highest each week, about half of them really are about to leave, compared with roughly one in ten if you pick at random. Then I showed three real customer examples and the main reasons the model flagged each one, like fewer orders and a recent complaint. She immediately asked how many calls her team could handle, which told me she'd understood, and we set the weekly list size around that."
Saying you walked a non-technical person through the model's metrics and algorithm in detail.
The expectation: what they wanted to hear and why it mattered to them.
Your check: how you made sure the result wasn't your mistake.
Delivery: how you shared it privately first and offered a way forward.
"A marketing lead had championed a referral campaign and asked me to measure its impact, clearly expecting a big win. When I compared customers who got the campaign with a similar holdout group, the lift in sign-ups was tiny and not distinguishable from noise. Before saying anything, I had a colleague review my method, and I checked whether any segment responded strongly. One did: existing customers with larger accounts. I met her one to one before the wider review, showed the overall result honestly, and then the segment where it did work. She was disappointed, but she took the idea of targeting that segment into the next quarter's plan, and the relationship stayed good."
Softening or reshaping the result to keep the stakeholder happy.
Local explanation: which features pushed this one score up or down, using a method like SHAP.
Plain words: turn it into two or three reasons the manager can repeat.
Limits: it explains the model, not the cause, and check for unfair signals.
"I'd pull a local explanation for that one application, for example SHAP values, which show how much each feature pushed this applicant's score up or down compared with the model's average prediction. Then I'd translate the top few into plain reasons, like a short credit history and a high ratio of existing debt to income. I'd be careful to say this is why the model scored them this way, not a proof of what caused their risk. I'd also look for anything uncomfortable in the top drivers, such as a feature acting as a stand-in for a protected group. In lending, rules in many places require clear reasons for a rejection, so this should be built in, not done case by case."
Saying the model is a black box so the decision can't be explained.
The decision: how big it is and how easy it is to reverse.
The test: would more work plausibly change the recommendation?
Honesty: share with clear caveats and a note on what's still being checked.
"I ask two questions. How big is the decision, and how easy is it to undo? Choosing an email subject line needs a quick, reasonable answer. Changing pricing for every customer deserves much more checking. The second question is whether more work could plausibly change my recommendation. If I've tested the main alternatives and the answer holds, more digging is mostly for my own comfort. When I share early, I say exactly how confident I am, what I haven't checked yet and what would change my mind. I'd rather give a useful answer on time with honest caveats than a perfect one after the decision has already been made without me."
Saying you never share until you're completely certain, or that you always share the first result you get.
Early: agree the problem and success measure with the PM before building.
Constraints: learn from engineers what data, latency and systems are realistic.
Ongoing: short check-ins, shared documents and honest updates when things slip.
"I like to bring both in at the start, not at the end. With the product manager, I agree what decision we're supporting and how we'll measure success, ideally in a short written brief so we both remember it later. With engineers, I ask early what data is available at prediction time, how fast the model needs to respond and how it will be deployed, because that can rule out an approach before I've spent weeks on it. During the project, I prefer short, regular check-ins and sharing rough results early. And I treat adoption as my job too, so after launch I stay involved to see whether people actually use the output."
Describing your job as handing a notebook over to engineers and moving on.
The problem: peeking many times raises the chance of a false win.
Other reasons: early days miss weekly cycles and novelty effects.
Way forward: finish the planned run, or use a method designed for early stopping next time.
"I'd explain that the significance threshold only means what we think it means if we look once, at the planned end. If we check every day and stop the first time it crosses, we give random noise many chances to look like a win, so the real false positive rate is much higher than we set. Three days also misses a full weekly cycle, and new features often get a burst of curiosity clicks that fades. So I'd recommend running the full two weeks. If the team often needs early decisions, I'd suggest we set up a sequential testing method next time, which is designed to allow looking early without inflating false positives."
Agreeing to stop because the p-value is already below the threshold.
Plan: hypothesis, primary metric, guardrail metrics and randomisation unit.
Size: baseline rate, smallest effect worth detecting, significance level and power set the sample size and duration.
Run and read: full weekly cycles, check the traffic split, then decide on the pre-agreed metric.
"I'd start with a hypothesis, like the new page reduces confusion so more people finish checkout. The primary metric would be completed purchases per user who reaches checkout, with guardrails such as average order value, refunds and page errors. I'd randomise by user, not by page view, so nobody sees both versions. Then I'd size it: from the current conversion rate, the smallest lift worth shipping, the significance level and the power, I'd get the users needed per group and turn that into a run time, rounded up to full weeks. While it runs, I'd check that the traffic split matches what we set, since a mismatch usually means a bug. At the end, I'd read the primary metric once and decide, checking guardrails before shipping."
Picking the metric after seeing the results, or running the test until it looks significant.
Precision: of everything flagged positive, how much really was positive.
Recall: of all the real positives, how many were flagged.
Choice: depends on whether false alarms or misses cost more; the threshold trades one for the other.
"Precision asks: of everything the model flagged, how many were really positive? Recall asks: of all the real positives out there, how many did the model catch? They pull against each other through the threshold. Lower it and you catch more, so recall goes up, but you also flag more wrong ones, so precision usually drops. Which one matters depends on the cost of each mistake. For an email that goes to a customer saying their account is suspended, I want high precision, because a false alarm annoys a real customer. For an early screen for a serious disease, where a positive just leads to a follow-up test, I want high recall, because missing a case is far worse than an extra test."
Mixing up the two definitions, or saying you'd simply maximise accuracy instead.
ROC-AUC: ranking quality across all thresholds; the chance a random positive scores above a random negative.
The trap: with very few positives, the false positive rate stays tiny even with many false alarms.
PR-AUC: focuses on the positive class; its baseline equals the share of positives.
"ROC-AUC measures how well the model ranks positives above negatives across every threshold. It equals the chance that a randomly chosen positive gets a higher score than a randomly chosen negative, and it doesn't depend on the class balance, which makes it good for comparing models when classes are reasonably balanced. The trouble comes when positives are rare, like fraud. The false positive rate divides by a huge number of negatives, so the model can raise thousands of false alarms and the ROC curve still looks excellent. Precision-recall AUC focuses on the positive class, so those false alarms show up directly as lower precision. Its baseline is the share of positives, not one half, so I'd always report that baseline alongside it."
Saying a high ROC-AUC means the model is useful, without asking how rare the positive class is.
RMSE: squares errors first, so large misses dominate.
MAE: treats every unit of error the same, more robust to outliers.
Choice: depends on whether one big miss is much worse than several small ones.
"Both are in the same units as the target, which makes them easy to explain, but they treat big errors differently. RMSE squares each error before averaging, so a few large misses pull it up a lot. MAE just averages the absolute errors, so every minute of error counts the same, and it's less swayed by outliers. For delivery times, I'd ask what hurts customers more. If being an hour late is far worse than being five minutes late several times, RMSE matches that pain. If there are odd outliers, like deliveries delayed by a strike, that I don't want dominating model choice, MAE is steadier. A useful detail: minimising squared error targets the mean, while minimising absolute error targets the median."
Saying RMSE is always better because it's more common, or not knowing it punishes large errors more.
Keep everyone: LEFT JOIN from users to orders so non-buyers stay with a NULL.
First purchase: MIN of order date per user, grouped at the user level.
Edge cases: date arithmetic differs by database; check orders dated before sign-up.
"I'd start from the users table and LEFT JOIN orders, because an inner join would silently drop everyone who never bought, and those are often the people the business cares about most. I group by user and take the minimum order date as the first purchase, then subtract the sign-up date. In Postgres, subtracting two dates gives a whole number of days; other databases use a date-difference function instead. Users with no orders come out with NULL, which is honest, and I'd keep it that way rather than turning it into zero, since zero would mean they bought on day one. I've put the date check in the join, so orders dated before sign-up are ignored without dropping the user, but I'd count them separately, because they usually point to a data problem worth raising."
-- Postgres: date minus date gives whole days
SELECT u.user_id,
u.signup_date,
MIN(o.order_date) AS first_order_date,
MIN(o.order_date) - u.signup_date AS days_to_first_order
FROM users u
LEFT JOIN orders o
ON o.user_id = u.user_id
AND o.order_date >= u.signup_date
GROUP BY u.user_id, u.signup_date;
Using an inner join and losing the users who never purchased.
Grain: one row per customer per day first, so windows count days, not rows.
Time window: a rolling window of 7D on a datetime index, grouped by customer.
Join back: merge on customer and date so values land on the right rows.
"First I'd make sure the date column is a real datetime and collapse the data to one row per customer per day, summing the amount. Then I'd group by customer and use a time-based rolling window of 7D on the date index. That matters, because rolling with the number seven counts the last seven rows, which could span months for an occasional buyer. A time-based window covers the current day and the six days before it. Grouping by customer keeps one person's spend from leaking into another's window. Finally, I merge the result back on customer and date, rather than assigning by position, so each value lands on the right row."
import pandas as pd
df["date"] = pd.to_datetime(df["date"])
daily = df.groupby(["customer_id", "date"], as_index=False)["amount"].sum()
rolled = (daily.sort_values("date")
.set_index("date")
.groupby("customer_id")["amount"]
.rolling("7D").sum()
.rename("spend_7d")
.reset_index())
daily = daily.merge(rolled, on=["customer_id", "date"], how="left")
Using a row-based window of seven and calling it seven days, or forgetting to group by customer.
ClapAssist is an AI interview assistant for Mac and Windows. It listens to the interview on your computer and shows you what to say, in short lines you can read while you talk. Your resume and notes are never stored on our servers. It stays out of screen share on every plan; only you can see it.