Back to blog
ChatGPT14 min read

How to Prompt ChatGPT for Data Analysis

ChatGPT data analysis prompts fail quietly: sentinel values, string-typed numbers, silent join drops. How to paste real data and make it show its work.

NH
Nafiul Hasan
Founder, Prompt Architects

TL;DR: ChatGPT genuinely analyzes a real dataset by writing and running actual Python, not by "remembering" your numbers, so paste or upload the real data rather than describing it. The failures that matter are quiet: a sentinel value averaged in, a number stored as text, rows dropped on a bad join. Ask for the code and the row counts, not just the answer, before you trust either.

Why Paste the Data Instead of Just Describing It?

Because a description invites the model to fill gaps from pattern-matching, and a real file forces it through actual code that either runs on your numbers or visibly fails.

ChatGPT will happily produce a specific-sounding average, growth rate, or forecast from a paragraph describing your data, and there is no way to tell from the output alone whether it computed that number or generated a plausible one the same way it generates any other confident sentence. That is the same underlying failure mode covered in why ChatGPT makes things up, applied to a spreadsheet instead of a fact.

A real uploaded file changes the mechanism entirely. The mechanics of that sandbox, what it can reach, how long a session lasts, which file types it accepts, are covered separately in our companion piece on prompting the code interpreter. This piece assumes you already have a real file in hand and covers what happens after you upload it, which is where most of the actual damage gets done.

The difference shows up immediately in how you phrase the first message. "Our churn rate has been rising, what's driving it?" invites a narrative answer built from whatever pattern the model expects to see in a churn story, regardless of what your actual numbers say. "Here is our subscriber file. Compute monthly churn for each of the last six months and show the formula you used" forces a specific calculation against specific rows, and that calculation either runs or errors, it does not get to be vaguely plausible instead. The second prompt is more work to type and it is the only one of the two that produces an answer worth repeating in a meeting.

A useful habit for the very first prompt in any analysis session is to set the ground rules before asking the actual question, rather than hoping the model volunteers them:

I am uploading a real file. Do not estimate, recall, or assume any
number that could instead be computed from the file. If a number
in your answer did not come from running code against this file,
label it UNVERIFIED.

That one instruction does not fix every failure mode below, but it removes the easiest way for a wrong number to slip through unlabeled: the model quietly reverting to a plausible-sounding guess when the real computation is inconvenient or the file is messy.

Where Does a ChatGPT Data Analysis Prompt Quietly Go Wrong?

In a small, specific set of places, and every one of them produces an answer that looks perfectly confident while being wrong.

A placeholder value pulled into the average. Real-world exports use sentinel numbers for missing data all the time: -999, 9999, or a birth year defaulting to 1900 where a real value was never recorded. Ask for a mean or median over that column and the placeholder gets averaged in as though it were real, quietly dragging the result in whatever direction the placeholder sits. Ask the model to show the minimum and maximum of any column before it aggregates that column, and a suspicious repeating value at the extreme end is usually a sentinel, not data. This is the same quiet-confidence problem behind hallucination, just wearing a spreadsheet instead of a sentence.

A column that is numbers everywhere except in your head. A price column exported as "$1,200" or "1,200 " with a trailing space or currency symbol reads as text, not a number, to a lot of tooling. If the code treats it as a string, rows with that formatting either get silently excluded from an aggregate or the model works around the error without telling you. Ask explicitly for the inferred data type of every column before the analysis starts, stated in the model's own output, not left to your assumption.

Rows that vanish on a join. Merging two files on a shared identifier is one of the things ChatGPT is documented to handle well: a customer file and a purchase file joined on a shared ID column is a standard example in OpenAI's own material on the feature. What is not advertised is that a join silently drops any row whose key does not match exactly on both sides. A trailing space, a different case, or a customer ID stored as 1024 in one file and "1024" in the other is enough to lose the row with no error message. Ask for the row count on each file before the merge and the row count after, and treat any drop as something to explain, not a detail to skip past.

A correlation you did not ask the model to test. Once two variables sit in the same aggregated table, it is a short step from "here is how X and Y move together" to a causal-sounding sentence like "X is driving the increase in Y," and the model will make that step for you if nothing stops it. None of this means a correlation is worthless. It means the sentence "X causes Y" needs a test you asked for and can defend, not one the model volunteered on its own.

Rows filtered out before you ever see the total. A denominator can shrink quietly. Ask for "the average order value for active customers" and the model has to decide what "active" means if your file does not define it, then apply that definition before it ever shows you a number. If it drops trial accounts, cancelled accounts, or rows with a blank signup date without saying so, the resulting average is real math on the wrong population. Ask for the definition it used and the row count it applied that definition to, every time a word like "active" or "valid" appears in your own question.

Silent failureWhat to ask for before you trust the number
Sentinel values pulled into an averageMinimum, maximum, and value counts for every column before aggregation
Numbers stored as textThe inferred data type of each column, stated explicitly
Rows dropped on a joinRow counts before and after every merge
Correlation read as causationA plain statement of what test, if any, was actually run
Rows filtered by an undefined wordThe exact definition applied, and the row count before and after the filter

A small illustrative example

Take a five-row order file, small enough to check by hand:

order_idcustomer_idamountstatus
11024"$1,200"complete
21024340complete
3"1024 "210complete
41099-999cancelled
51102875complete

Ask for "the average order amount" with no further instruction, and a plausible-looking failure can run through more than one of these problems at once. Row 1's amount is a string because of the currency symbol, so it might get silently dropped rather than read as 1,200. Row 4's -999 is a cancellation sentinel, so it might get averaged in as if it were a real amount instead of being excluded. Row 3's customer_id has a trailing space, so it might fail to match cleanly against a separate customer table. Depending on which of those actually happens, you get a confident-looking figure that does not match what a human checking the five rows by hand would produce, and nothing in a bare answer tells you which mistake it was.

Asked instead with the shape-first instruction from the next section, the correct read is: three genuinely completed orders with real amounts (rows 1, 2, and 5, once the currency symbol is stripped) average to exactly 805.00, row 4 is excluded because its status is cancelled and its amount is a sentinel rather than a value, and row 3 needs its customer_id trimmed before any join against a separate customer table. Five rows is small enough to catch this by eye. A 50,000-row export is not, which is exactly why the instruction below has to be a habit rather than something you only reach for when a number already looks wrong.

What Is the Single Most Useful Instruction You Can Give It Here?

Make it show the code and the intermediate shape of the data, not just the final answer.

A number with no visible derivation is unverifiable. You cannot tell whether a total was computed correctly, computed over the wrong rows, or generated from pattern-matching alone unless the steps that produced it are sitting in front of you. This is the single habit that catches the most problems listed above, before you even get to checking the number itself.

Before answering, run and show:
1. df.shape
2. df.dtypes
3. df.head(5)
4. Value counts for any column you are about to aggregate

Only after showing all four, compute the actual answer. Show the
exact code for that computation too, not just the result.

Pair it with a prompt that forces the model to account for anything it drops along the way:

If any rows are excluded, filtered, or dropped at any step, state
how many and why, in a line that starts with EXCLUDED:. If nothing
was excluded, state that explicitly.

How Do You Actually Verify a Number Before You Trust It?

By checking a small sample yourself and making the model account for the one input that would change the answer the most if it were wrong.

Pick a handful of rows at random from the raw file and recompute the metric by hand, or in a spreadsheet, for just those rows. If the model's per-row logic is wrong, it is usually wrong in a way that shows up even in a tiny sample. Then ask for the total row count used in the final calculation and compare it to the row count of the file you actually uploaded. Any gap is either a documented filter or an unexplained loss, and you want to know which before the number goes anywhere important.

A second, cheap check is asking for the same number two different ways and seeing whether they agree. A total revenue figure should equal both "sum of amount across all completed orders" and "sum of price times quantity across all completed order lines," computed as two separate pieces of code rather than one number quoted twice. If a model states the same figure both times without actually running two separate calculations, that is worth noticing on its own; agreement between two prompts asked for a genuinely independent recomputation means more than agreement between two sentences that both came from the same first pass.

The last check is the one worth making a habit: ask which single input, if it were wrong, would change the final number the most, and have the model recompute using only that input, taken from the raw file again rather than from its own earlier working.

Recompute [the specific figure] two ways: first as you already
did, second as an independent calculation that does not reuse any
intermediate variable from the first attempt. State whether the
two agree. If they do not, show both sets of code side by side.

None of this amounts to a fixed rule about how many rows to check or how big a sample needs to be. It is a habit of checking something concrete rather than a threshold to hit, and a five-row spot check that actually gets done catches more real errors than a rule you meant to apply and skipped.

Why Does a Date or Duration Column Never Add Up?

Because date and arithmetic are two of the specific places a language model is documented to struggle, even when the rest of its reasoning is solid, and that is a separate problem from the analysis workflow itself.

We have already covered the mechanism, how numbers get tokenized and why there is no clock inside the model, in full in why AI gets dates and arithmetic wrong, and there is no point re-deriving it here. The short version for a data-analysis prompt: any column involving dates, ages, or durations should go through the same code-execution path as the rest of the analysis, with the reference date stated explicitly in the prompt rather than assumed.

Turning This Into a Repeatable Habit

If your raw data starts life as a screenshot or a scanned printout rather than a real spreadsheet, that is a separate problem covered in prompting ChatGPT with images. Expect it to read less precisely than a real file, for the same reasons covered in our companion piece on the sandbox itself. And if the deliverable needs to come out as a clean table rather than a paragraph of prose, prompting for tables and structured data is the separate skill that gets you there.

None of the habits above are complicated on their own. The hard part is running them every time instead of only after a number has already turned out to be wrong. Paste the real data. Ask for the shape before the answer. Check the row counts on both sides of anything that merges. Ask what test supports a causal claim before repeating one.

The five-row example earlier in this piece is small enough to hold in your head. Most real files are not, which is exactly why the checks have to survive being applied to something you cannot eyeball. A verification habit that only works on data small enough to read by eye is not really a habit, it is a coincidence that happened to hold up once. Build the shape-first prompt and the row-count check into how you open every analysis, not into what you reach for after a number has already made it into a slide.

Prompt Architects does not do the analysis for you. It is a prompt generator and library, and what it saves you is retyping the verification block above from memory every time you open a fresh chat and a new file.

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account

Frequently asked questions

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account