E-commerce Sales Analysis in Python

Explore an e-commerce sales dataset with monthly trends, top products, category breakdowns, and average order value analysis.

This page shows an AI data analysis example. A workflow is a list of prompts (instructions) used to complete one analysis task step by step. We send the same prompt list to multiple AI models, then compare their notebook outputs and scores.

What this AI workflow does

This AI Data Analyst workflow loads the Online Retail Excel dataset from a URL and summarizes its structure with shape, dtypes, and missing values. It generates exploratory visuals for monthly revenue trends and identifies the top 10 products by total revenue. It computes average order value and compares AOV across countries with a focused country-level breakdown.

Who this example is for

This is for analysts and data scientists who want a conversational, code-generating EDA template for e-commerce transaction data in Python. It helps users quickly validate data quality and produce standard sales KPIs and plots for reporting or further modeling.

Expected analysis outcomes

These are the results the AI workflow is expected to generate.

  • Dataset shape, dtypes, and null counts
  • Monthly revenue trend line chart
  • Top 10 products by total revenue bar chart
  • Average order value overall and by country
  • Bar chart of top countries by AOV

Tools and libraries used

Main Python packages and tooling used to run this AI data analysis task.

  • pandas
  • numpy
  • matplotlib
  • seaborn
  • openpyxl

Prompt sequence

This is the exact list of prompts used in this workflow. The same prompt sequence is sent to each model so outputs and scores can be compared fairly.

  1. 1load the retail sales dataset from https://raw.githubusercontent.com/pplonski/datasets-for-start/refs/heads/master/online-retail/Online-Retail.xlsx and show basic info and shape
  2. 2plot monthly revenue trend
  3. 3show top 10 products by total revenue
  4. 4what is the average order value and how does it vary by country?

Model Comparison

We compared several LLM models on the same analysis task. The table below shows their scores side by side. You can also open each model run to check the full conversation and notebook results.

Model SourceScoreTaskExecutionOutputReasoningReliabilityRun
glm-5.110/102/22/23/32/21/1Open glm-5.1 conversation
gpt-5.410/102/22/23/32/21/1Open gpt-5.4 conversation
gpt-oss:120b10/102/22/23/32/21/1Open gpt-oss:120b conversation
qwen3.5:397b10/102/22/23/32/21/1Open qwen3.5:397b conversation
gemma4:31b9/102/22/23/31/21/1Open gemma4:31b conversation
qwen3-coder-next9/102/22/23/31/21/1Open qwen3-coder-next conversation
How scoring works

Each run is graded on five dimensions:

  • Task Completion (0-2): how fully the workflow answered the requested analysis task and completed required steps.
  • Execution Correctness (0-2): whether generated code is correct, consistent, and likely runnable without major fixes.
  • Output Quality (0-3): how well tables, charts, and results match the expected analytical outcomes.
  • Reasoning Quality (0-2): clarity and correctness of interpretation, explanation, and conclusions.
  • Reliability (0-1): robustness of the run, including low hallucination risk and stable behavior.

The final score is the sum of these dimensions, so total score = 0-10. Higher values indicate more complete, correct, and reliable notebook results for this workflow.

AI Analysis with gemma4:31b

This run uses AI with a step-by-step list of prompts to perform the analysis task E-commerce Sales Analysis in Python. Below, you can review the full conversation generated with gemma4:31b. After the conversation, we show detailed score cards for this run.

load the retail sales dataset from https://raw.githubusercontent.com/pplonski/datasets-for-start/refs/heads/master/online-retail/Online-Retail.xlsx and show basic info and shape
Thinking

The user wants to load a specific retail sales dataset from a URL, display basic information, and the shape of the dataframe.

Plan:

  1. Use pandas to read the Excel file from the provided URL.
  2. Use df.info() and df.shape to show the requested information.
  3. Since this is the first load, I must follow the rule: "When a dataset is not yet loaded... first load and inspect only: show shape, columns, and head()."

Execution:

  • Import pandas.
  • Read the excel file.
  • Display df.shape.
  • Display df.columns.
  • Display df.head().

I'll start by loading the dataset from the provided URL and performing a basic inspection of its structure.

Load and inspect data
import pandas as pd

# Load the dataset
url = "https://raw.githubusercontent.com/pplonski/datasets-for-start/refs/heads/master/online-retail/Online-Retail.xlsx"
df = pd.read_excel(url)

# Basic inspection
display(df.shape)
display(df.columns)
display(df.head())
(541909, 8)
Index(['InvoiceNo', 'StockCode', 'Description', 'Quantity', 'InvoiceDate',
       'UnitPrice', 'CustomerID', 'Country'],
      dtype='str')
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
Thinking

The user wants to load the dataset from a specific URL and show basic info and shape. The notebook state shows that pd.read_excel was used, and display(df.shape), display(df.columns), and display(df.head()) were executed. The output is:

  • Shape: (541909, 8)
  • Columns: ['InvoiceNo', 'StockCode', 'Description', 'Quantity', 'InvoiceDate', 'UnitPrice', 'CustomerID', 'Country']
  • Head: Shows the first 5 rows.

The original goal was to "load the retail sales dataset... and show basic info and shape". The latest output provides the shape (541,909 rows and 8 columns), the column names, and a preview of the data. This satisfies the request for basic info and shape.

Therefore, I should follow Path A.

Final answer content: The dataset has been loaded and contains 541,909 records and 8 columns. The columns are InvoiceNo, StockCode, Description, Quantity, InvoiceDate, UnitPrice, CustomerID, and Country. The preview shows transaction details, including quantities and unit prices (e.g., 2.55 USD, 3.39 USD).

Wait, I need to be careful about the currency formatting. "2.55 USD".

The prompt says: "Return only user-facing answer content... Do not include chain-of-thought... Return only user-facing answer content."

Final answer based on observed outputs: The retail sales dataset contains 541,909 rows and 8 columns: InvoiceNo, StockCode, Description, Quantity, InvoiceDate, UnitPrice, CustomerID, and Country. The initial rows show transactions with unit prices such as 2.55 USD and 3.39 USD.

<!--final answer-->

The retail sales dataset has been loaded with a shape of 541,909 rows and 8 columns. The columns include InvoiceNo, StockCode, Description, Quantity, InvoiceDate, UnitPrice, CustomerID, and Country. A preview of the data shows individual item transactions with unit prices such as 2.55 USD and 3.39 USD.

plot monthly revenue trend
Thinking

The user wants to plot the monthly revenue trend.

*   `df` is available.
*   Columns: `InvoiceNo`, `StockCode`, `Description`, `Quantity`, `InvoiceDate`, `UnitPrice`, `CustomerID`, `Country`.
*   `InvoiceDate` is likely in datetime format (since it's from an Excel file and looks like dates), but I should ensure it is.
*   Revenue is not a column. It needs to be calculated as `Quantity * UnitPrice`.

*   Create a `Revenue` column: `df['Revenue'] = df['Quantity'] * df['UnitPrice']`.
*   Convert `InvoiceDate` to datetime (just in case).
*   Resample or group by month.
*   Plot the trend using seaborn.

*   Step 1: Feature engineering (calculate revenue) and data aggregation.
*   Step 2: Plotting.
*   Since I can only do one primary objective per response and one code block, I'll handle the calculation and the plot in one go as it's a single "visualize" request.

*   `df['Revenue'] = df['Quantity'] * df['UnitPrice']`
*   `df['Month'] = df['InvoiceDate'].dt.to_period('M')` (requires `InvoiceDate` to be datetime).
*   Aggregate: `monthly_revenue = df.groupby('Month')['Revenue'].sum().reset_index()`
*   Plotting: `sns.lineplot(data=monthly_revenue, x='Month', y='Revenue')`. Wait, `Period` objects can be tricky with seaborn/matplotlib, better to convert `Month` back to timestamp.

*   Calculation: `df['TotalAmount'] = df['Quantity'] * df['UnitPrice']`
*   Convert `InvoiceDate` to datetime.
*   Group by month and sum.
*   Plot using seaborn.

*   Wait, let's check if there are negative quantities (returns). Often in retail datasets, negative quantities indicate returns. I should probably include them or filter them depending on the goal, but usually, for "revenue trend", we keep the net total.

*   Library: Seaborn/Matplotlib.
*   Formatting: `USD` for currency values in prose.

*   Calculation + Plotting.

*Wait*, the system says "one primary objective per response (for example: load, inspect, clean, plot, or model)".
And "If multiple code actions are required, do only the first action now".
Calculating revenue is a "clean/prep" step. Plotting is a "plot" step.
However, usually, creating a derived column for a plot is considered part of the plotting workflow. But to be safe and iterative, I'll do the calculation first or just do the whole pipeline if it's simple. Let's do the calculation and plotting in one go as "plotting monthly revenue" is the specific goal.

*Self-Correction*: "Default chart library: seaborn".
*Currency rule*: Use `USD`.

Let's refine the code:
1. Ensure `InvoiceDate` is datetime.
2. Calculate `Revenue`.
3. Aggregate by month.
4. Plot.

Wait, the user says "plot monthly revenue trend". I will provide the code to calculate and plot it.

*Implementation detail*:
`df['InvoiceDate'] = pd.to_datetime(df['InvoiceDate'])`
`df['Revenue'] = df['Quantity'] * df['UnitPrice']`
`monthly_rev = df.set_index('InvoiceDate')['Revenue'].resample('M').sum().reset_index()`
`sns.lineplot(data=monthly_rev, x='InvoiceDate', y='Revenue')`

Let's write the response.

To plot the monthly revenue trend, I first need to calculate the total price for each line item (Quantity × Unit Price) and then aggregate these values by month.

Plot monthly revenue trend
import matplotlib.pyplot as plt
import seaborn as sns

# Ensure InvoiceDate is in datetime format
df['InvoiceDate'] = pd.to_datetime(df['InvoiceDate'])

# Calculate revenue for each row
df['Revenue'] = df['Quantity'] * df['UnitPrice']

# Resample to get monthly total revenue using 'ME' (Month End) as required by newer pandas versions
monthly_revenue = df.set_index('InvoiceDate')['Revenue'].resample('ME').sum().reset_index()

# Plot the trend
plt.figure(figsize=(12, 6))
sns.lineplot(data=monthly_revenue, x='InvoiceDate', y='Revenue', marker='o')
plt.title('Monthly Revenue Trend')
plt.xlabel('Month')
plt.ylabel('Revenue (USD)')
plt.grid(True)
plt.show()
Thinking

The user wants to plot the monthly revenue trend. The notebook state shows that df was loaded and a plot was generated in [cell-2]. The output of [cell-2] shows <Figure size 1200x600 with 1 Axes>, but the actual numeric values for monthly_revenue are not displayed in the notebook context (only the plot was generated).

According to the "Sufficiency heuristics":

  • "If the latest output is chart-only/visual-only and does not include underlying numeric/text values, choose Path B first to print the values used in the chart."

Therefore, I must choose Path B to display the numeric values of the monthly_revenue dataframe to provide concrete insights along with the visualization.

Insights from current state:

  • The data was successfully resampled to monthly frequency using ME.
  • Revenue was calculated as Quantity * UnitPrice.
  • A line plot was generated, though the exact numbers are not visible in the provided output log.

Next step: Display the monthly_revenue table to complement the plot and allow for numeric analysis.

The monthly revenue trend has been plotted, showing the fluctuations in sales over time. To complement this visualization with precise numbers and identify the peak revenue months, I will display the aggregated monthly revenue data.

Display monthly revenue
display(monthly_revenue)
InvoiceDate Revenue
0 2010-12-31 748957.020
1 2011-01-31 560000.260
2 2011-02-28 498062.650
3 2011-03-31 683267.080
4 2011-04-30 493207.121
5 2011-05-31 723333.510
6 2011-06-30 691123.120
7 2011-07-31 681300.111
8 2011-08-31 682680.510
9 2011-09-30 1019687.622
10 2011-10-31 1070704.670
11 2011-11-30 1461756.250
12 2011-12-31 433668.010
Thinking

The original user goal is to "plot monthly revenue trend". The current state of the notebook:

  • Cell 1: Loaded the dataset.
  • Cell 2: Calculated revenue, resampled by month ('ME'), and plotted a line chart of monthly revenue.
  • Cell 3: Displayed the monthly_revenue DataFrame containing the exact numeric values for each month.

The output includes both the visualization (the plot) and the supporting data (the monthly_revenue table). The data shows a growth trend starting from December 2010 (748,957.02 USD), peaking in November 2011 (1,461,756.25 USD), and then dropping significantly in December 2011 (433,668.01 USD), likely due to incomplete data for the final month.

Since both the chart and the numeric values are available, the goal has been fully met.

Path A is appropriate.

Insights:

  • Revenue peaked in November 2011 at 1,461,756.25 USD.
  • There was a steady increase in revenue from February 2011 (498,062.65 USD) through November 2011.
  • The sharp decline in December 2011 to 433,668.01 USD suggests the dataset might be truncated for that month.

Final Answer format: provide the insights and the tag <!--final answer-->. No code.

The monthly revenue trend plot and the corresponding data show that revenue grew steadily throughout 2011, starting from a low of 493,207.12 USD in April and peaking in November 2011 at 1,461,756.25 USD. The significant drop to 433,668.01 USD in December 2011 likely indicates that the data for the final month is incomplete.

show top 10 products by total revenue
Thinking

The user wants to find the top 10 products by total revenue. Looking at the notebook state:

  • df is the main DataFrame containing Description, Quantity, UnitPrice, and Revenue.
  • Revenue column has already been calculated as Quantity * UnitPrice.

Plan:

  1. Group the original df by Description.
  2. Sum the Revenue for each product.
  3. Sort the results in descending order.
  4. Take the top 10.

The Description column represents the product name. I should use that for grouping.

Steps:

  • Group by 'Description' and sum 'Revenue'.
  • Sort by 'Revenue' descending.
  • Head(10).

To find the top 10 products by total revenue, I will group the data by the product description and sum the revenue for each.

Get top 10 products
# Group by Description and sum Revenue, then get the top 10
top_products = df.groupby('Description')['Revenue'].sum().sort_values(ascending=False).head(10).reset_index()

display(top_products)
Description Revenue
0 DOTCOM POSTAGE 206245.48
1 REGENCY CAKESTAND 3 TIER 164762.19
2 WHITE HANGING HEART T-LIGHT HOLDER 99668.47
3 PARTY BUNTING 98302.98
4 JUMBO BAG RED RETROSPOT 92356.03
5 RABBIT NIGHT LIGHT 66756.59
6 POSTAGE 66230.64
7 PAPER CHAIN KIT 50'S CHRISTMAS 63791.94
8 ASSORTED COLOUR BIRD ORNAMENT 58959.73
9 CHILLI LIGHTS 53768.06
Thinking

The user wants to see the top 10 products by total revenue. The latest notebook output (cell-4) shows a table top_products containing the top 10 Description and their corresponding Revenue.

The outputs are: 0. DOTCOM POSTAGE: 206,245.48 USD

  1. REGENCY CAKESTAND 3 TIER: 164,762.19 USD
  2. WHITE HANGING HEART T-LIGHT HOLDER: 99,668.47 USD
  3. PARTY BUNTING: 98,302.98 USD
  4. JUMBO BAG RED RETROSPOT: 92,356.03 USD
  5. RABBIT NIGHT LIGHT: 66,756.59 USD
  6. POSTAGE: 66,230.64 USD
  7. PAPER CHAIN KIT 50'S CHRISTMAS: 63,791.94 USD
  8. ASSORTED COLOUR BIRD ORNAMENT: 58,959.73 USD
  9. CHILLI LIGHTS: 53,768.06 USD

The goal is "show top 10 products by total revenue". The output of cell-4 provides exactly this information.

According to the A/B decision policy: A) If current outputs are sufficient, provide a natural final answer. B) If not sufficient, provide insights and a code block.

The current outputs are sufficient. I will provide the final answer based on the table.

Formatting:

  • Use USD instead of $.
  • No code blocks.
  • No headers.
  • Concise and conversational.

The top 10 products by total revenue are led by DOTCOM POSTAGE, generating 206,245.48 USD, followed by the REGENCY CAKESTAND 3 TIER at 164,762.19 USD. Other high-revenue items include the WHITE HANGING HEART T-LIGHT HOLDER (99,668.47 USD) and PARTY BUNTING (98,302.98 USD). The list is rounded out by items such as JUMBO BAG RED RETROSPOT, RABBIT NIGHT LIGHT, and CHILLI LIGHTS, with the 10th product contributing 53,768.06 USD.

what is the average order value and how does it vary by country?
Thinking

The user wants to know the Average Order Value (AOV) and how it varies by country.

*   `df` exists and contains columns: `InvoiceNo`, `StockCode`, `Description`, `Quantity`, `InvoiceDate`, `UnitPrice`, `CustomerID`, `Country`, `Revenue`.
*   `Revenue` is already calculated (`Quantity * UnitPrice`).
*   An "Order" is typically defined by a unique `InvoiceNo`.

*   AOV = Total Revenue / Total Number of Unique Orders.
*   To find AOV by country:
    1.  Group by `Country` and `InvoiceNo` to get total revenue per order per country.
    2.  Group that result by `Country` to get the average revenue per order.

*   Step 1: Calculate the total revenue for each order (unique `InvoiceNo`) and keep the `Country` associated with it.
*   Step 2: Calculate the mean of these order totals grouped by `Country`.
*   Step 3: Show the overall AOV and a table/plot for AOV by country.

*Decision:* I'll start by calculating the order-level revenue and then the AOV per country. Since I need to provide one step at a time, I'll first compute the order-level aggregation and the overall average.

Wait, the user asked for both the general AOV and how it varies by country. I can do this in one analysis step.

*Calculation logic:*
`order_totals = df.groupby(['Country', 'InvoiceNo'])['Revenue'].sum().reset_index()`
`aov_by_country = order_totals.groupby('Country')['Revenue'].mean().sort_values(ascending=False).reset_index()`

Let's start by calculating the order totals and the overall AOV.

*Refined plan:*
1. Calculate total revenue per unique order (InvoiceNo) including the country.
2. Calculate the overall average of these totals.
3. Group these totals by country to see the variation.

I will provide code to calculate the AOV by country and the overall average.

*Wait, the system instruction says "Prefer one execution step at a time." and "Default to one chart OR one table per step."*

I'll first calculate the order-level totals and display the AOV per country as a table.

*Code draft:*
```python
# Calculate total revenue per order (InvoiceNo) per Country
order_totals = df.groupby(['Country', 'InvoiceNo'])['Revenue'].sum().reset_index()

# Calculate AOV per country
aov_by_country = order_totals.groupby('Country')['Revenue'].mean().sort_values(ascending=False).reset_index()
aov_by_country.columns = ['Country', 'AverageOrderValue']

# Overall AOV
overall_aov = order_totals['Revenue'].mean()

print(f"Overall Average Order Value: {overall_aov:.2f} USD")
display(aov_by_country)
```

Wait, the user prompt is "what is the average order value and how does it vary by country?".
I will execute this.

*Correction:* I should be careful about the `Revenue` column. It's already in `df`.

Let's double-check if any filtering is needed (e.g., negative quantities for returns). The original dataset often has returns (Quantity < 0). The current `Revenue` was calculated as `Quantity * UnitPrice`. Returns will subtract from the revenue, which is correct for total revenue, but for "Average Order Value", usually, we are looking at successful transactions or net value. I'll stick to the current `Revenue` column for consistency with the previous steps.

One table per step. I'll show the AOV by country and print the overall AOV.

*Final check on rules:*
- Markdown for text.
- Python code blocks.
- Currency as `USD`.
- No `$` sign for money.
- No multiple code blocks.
- No end-to-end pipeline.
- Bare expression at end of block.

Let's refine the code to be minimal.

```python
# Calculate total revenue per unique order
order_totals = df.groupby(['Country', 'InvoiceNo'])['Revenue'].sum().reset_index()

# Calculate AOV by country
aov_by_country = order_totals.groupby('Country')['Revenue'].mean().sort_values(ascending=False).reset_index()
aov_by_country.columns = ['Country', 'AOV']

# Calculate overall AOV
overall_aov = order_totals['Revenue'].mean()

print(f"Overall Average Order Value: {overall_aov:.2f} USD")
aov_by_country
```

Actually, I'll just return the table and print the overall AOV.

Wait, I should check if the user wants a visualization. "How does it vary" suggests a comparison. A table is fine, but a bar chart might be better. I'll start with the table as per "Default to one chart OR one table per step."

Wait, if I print `overall_aov` and display the table, that's one "output" essentially.

Let's go.

To determine the Average Order Value (AOV), I first need to calculate the total revenue for each unique order (InvoiceNo) and then average those totals.

Calculate average order value
# Calculate total revenue per order per country
order_totals = df.groupby(['Country', 'InvoiceNo'])['Revenue'].sum().reset_index()

# Calculate AOV by country
aov_by_country = order_totals.groupby('Country')['Revenue'].mean().sort_values(ascending=False).reset_index()
aov_by_country.columns = ['Country', 'AOV']

# Calculate overall AOV
overall_aov = order_totals['Revenue'].mean()

print(f"Overall Average Order Value: {overall_aov:.2f} USD")
aov_by_country
Overall Average Order Value: 376.36 USD
Country AOV
0 Netherlands 2818.431089
1 Australia 1986.627101
2 Lebanon 1693.880000
3 Japan 1262.165000
4 Brazil 1143.600000
5 RSA 1002.310000
6 Singapore 912.039000
7 Denmark 893.720952
8 Norway 879.086500
9 Israel 878.646667
10 Sweden 795.563261
11 Greece 785.086667
12 Switzerland 761.964189
13 EIRE 731.324500
14 Hong Kong 674.469333
15 Cyprus 647.314500
16 United Arab Emirates 634.093333
17 Iceland 615.714286
18 Canada 611.063333
19 Channel Islands 608.675455
20 Austria 534.437895
21 Spain 521.662667
22 Finland 465.140417
23 France 428.208026
24 Lithuania 415.265000
25 Portugal 413.620000
26 Germany 367.658723
27 Unspecified 365.368462
28 United Kingdom 348.506272
29 Belgium 343.789580
30 Italy 307.100182
31 Poland 300.547500
32 European Community 258.350000
33 Malta 250.547000
34 USA 247.274286
35 Czech Republic 141.544000
36 Bahrain 137.100000
37 Saudi Arabia 65.585000
Thinking

The user wants to know the average order value (AOV) and how it varies by country. Looking at the notebook state:

  • Cell 5 calculated the overall AOV as 376.36 USD.
  • Cell 5 also calculated the AOV by country and displayed a sorted list.
  • The output for aov_by_country shows the top countries: Netherlands (2818.43 USD), Australia (1986.63 USD), Lebanon (1693.88 USD), etc.
  • The output is truncated, but the main request ("what is the average order value and how does it vary by country?") has been answered numerically.
  • I have the overall AOV and the distribution across countries.

Decision: Path A. The current outputs are sufficient to answer the original goal.

Insights:

  • Overall AOV: 376.36 USD.
  • Variation: There is a significant variation across countries. The Netherlands has the highest AOV at 2818.43 USD, followed by Australia at 1986.63 USD. These are substantially higher than the overall average.

Final answer formatting:

  • Use USD notation.
  • Natural language.
  • No code.
  • No headings.
  • End with <!--final answer-->.

The overall Average Order Value (AOV) is 376.36 USD. There is significant variation by country, with the Netherlands seeing the highest average order value at 2818.43 USD, followed by Australia at 1986.63 USD and Lebanon at 1693.88 USD. These figures are considerably higher than the global average, indicating that order sizes vary greatly depending on the region.

Score cards for gemma4:31b for E-commerce Sales Analysis in Python

Total score: 9/10

  • Task Completion: 2/2

    Excellent

    The notebook completed all major requested analyses: dataset loading/basic inspection, monthly revenue trend, top 10 products by revenue, and AOV by country.

  • Execution Correctness: 2/2

    Excellent

    The code shown is coherent and likely runnable, with valid pandas grouping, resampling, and plotting steps. No major syntax or logic errors are evident from the provided content.

  • Output Quality: 3/3

    Excellent

    Outputs match the expected outcomes semantically: shape/dtypes-like inspection, a monthly revenue line chart, top 10 products table, and country-level AOV results including overall AOV.

  • Reasoning Quality: 1/2

    Needs work

    The assistant’s reasoning is mostly correct but verbose and somewhat repetitive, with unnecessary self-corrections. It still identifies the needed calculations and analyses appropriately.

  • Reliability: 1/1

    Excellent

    The workflow is consistent and grounded in the dataset outputs, though it includes some extraneous reasoning and a minor pandas resampling choice that may depend on version specifics.

Try MLJAR Studio

Run the same type of AI-powered data analysis on your own datasets with conversational notebooks in MLJAR Studio.

Explore More AI Analysis Examples

Discover additional workflows across categories. Each example includes prompts, conversation outputs, and model-level scoring so you can compare approaches and results.