Average Transaction Value Stats
This skill covers computing mean eur_amount from payments.csv, with optional filters on merchant, card scheme, and month range, grouped by a categorical column.
Dataset Overview
payments.csv — core transaction table. Key columns:
merchant: Crossfit_Hanna, Rafa_AI, Golfclub_Baron_Friso, Belles_cookbook_store, Martinis_Fine_Steakhouse
card_scheme: NexPay, GlobalCard, SwiftCharge, TransactPlus
year: always 2023 in this dataset
day_of_year: 1–365 (no month column — compute month ranges using the table below)
eur_amount: transaction amount in euros
shopper_interaction: Ecommerce or POS
issuing_country: BE, ES, FR, GR, IT, LU, NL, SE
acquirer_country: FR, GB, IT, NL, US (NOT the same as issuing_country values)
ip_country: BE, ES, FR, GR, IT, LU, NL, SE
aci: A, B, C, D, E, F, G
device_type: Windows, Linux, MacOS, iOS, Android, Other
is_credit: True or False
card_bin: 13 possible values (e.g., 4017, 4133, 4236, ...)
email_address: hashed email (has NaN values — groupby excludes NaN automatically)
card_number, ip_address: hashed IDs (no NaN)
Merchant → acquirer_country mapping (each merchant has a fixed acquirer):
Belles_cookbook_store → US
Crossfit_Hanna → NL (majority) and GB
Golfclub_Baron_Friso → IT
Martinis_Fine_Steakhouse → FR
Rafa_AI → NL
Month → day_of_year Mapping (2023, non-leap year)
| Month |
day_of_year range |
| January |
1–31 |
| February |
32–59 |
| March |
60–90 |
| April |
91–120 |
| May |
121–151 |
| June |
152–181 |
| July |
182–212 |
| August |
213–243 |
| September |
244–273 |
| October |
274–304 |
| November |
305–334 |
| December |
335–365 |
Use (df['day_of_year'] >= start) & (df['day_of_year'] <= end) to filter date ranges.
Critical Filtering Rules
Card scheme is a filter column, not part of the merchant name
When a question says "Merchant_X's TransactPlus transactions", it means:
df[(df['merchant'] == 'Merchant_X') & (df['card_scheme'] == 'TransactPlus')]
Never omit the card_scheme filter when a card scheme is mentioned in the question.
Multi-month ranges
"Between January and April" means months January through April inclusive (day_of_year 1–120). Include both endpoint months.
Standard Solution Pattern
import pandas as pd
df = pd.read_csv('/path/to/payments.csv')
# 1. Apply all filters the question specifies
mask = pd.Series([True] * len(df), index=df.index)
# Optional: filter by merchant
mask &= (df['merchant'] == 'Merchant_Name')
# Optional: filter by card scheme
mask &= (df['card_scheme'] == 'CardSchemeName')
# Optional: filter by date range
mask &= (df['day_of_year'] >= DAY_START) & (df['day_of_year'] <= DAY_END)
filtered = df[mask]
# 2. Group by the specified column and compute mean eur_amount
result = filtered.groupby('grouping_column')['eur_amount'].mean()
# 3. Round to 2 decimal places (unless question specifies otherwise)
result = result.round(2)
# 4. Sort ascending by value
result = result.sort_values(ascending=True)
# 5. Format as list of strings
answer = [f"{idx}: {val}" for idx, val in result.items()]
print(answer)
Output Format
- List of grouped averages:
['GroupA: 71.18', 'GroupB: 86.79', ...]
- Sorted in ascending order by amount
- Amounts rounded to 2 decimal places
- Use the grouping key exactly as it appears in the data (e.g.,
FR, SE, Ecommerce)
- Single scalar average: return as a number (e.g.,
90.696)
Interpreting "Average per Unique X"
When the question asks for "average transaction amount per unique email/card/customer":
Common Mistakes to Avoid
- Wrong acquirer_country values: acquirer_country is
FR, GB, IT, NL, US — not the same as issuing_country (BE, ES, FR, GR, IT, LU, NL, SE).
- Missing card_scheme filter: "NexPay transactions" =
card_scheme == 'NexPay', not just merchant filter.
- Wrong date range: Verify month boundaries from the table. September–October is days 244–304.
- Sorting direction: Always sort ascending by
eur_amount unless the question says descending.
- Rounding display: Use
f"{val:.2f}" to show trailing zeros when formatting strings.
- NaN in email_address:
groupby automatically excludes NaN keys — no need to drop them explicitly.
1---2name: average-transaction-value-stats-23description: Skill for computing average transaction value statistics from payment transaction data in the dabstep dataset. Use this skill when a question asks about average transaction amount/value grouped by a categorical field (e.g., shopper_interaction, issuing_country, acquirer_country, aci, device_type, ip_country, is_credit, card_scheme, card_bin), possibly filtered by merchant, card scheme, and/or date range.4---56# Average Transaction Value Stats78This skill covers computing mean `eur_amount` from `payments.csv`, with optional filters on merchant, card scheme, and month range, grouped by a categorical column.910## Dataset Overview1112**`payments.csv`** — core transaction table. Key columns:13- `merchant`: `Crossfit_Hanna`, `Rafa_AI`, `Golfclub_Baron_Friso`, `Belles_cookbook_store`, `Martinis_Fine_Steakhouse`14- `card_scheme`: `NexPay`, `GlobalCard`, `SwiftCharge`, `TransactPlus`15- `year`: always 2023 in this dataset16- `day_of_year`: 1–365 (no month column — compute month ranges using the table below)17- `eur_amount`: transaction amount in euros18- `shopper_interaction`: `Ecommerce` or `POS`19- `issuing_country`: `BE`, `ES`, `FR`, `GR`, `IT`, `LU`, `NL`, `SE`20- `acquirer_country`: `FR`, `GB`, `IT`, `NL`, `US` (NOT the same as issuing_country values)21- `ip_country`: `BE`, `ES`, `FR`, `GR`, `IT`, `LU`, `NL`, `SE`22- `aci`: `A`, `B`, `C`, `D`, `E`, `F`, `G`23- `device_type`: `Windows`, `Linux`, `MacOS`, `iOS`, `Android`, `Other`24- `is_credit`: `True` or `False`25- `card_bin`: 13 possible values (e.g., 4017, 4133, 4236, ...)26- `email_address`: hashed email (has NaN values — `groupby` excludes NaN automatically)27- `card_number`, `ip_address`: hashed IDs (no NaN)2829**Merchant → acquirer_country mapping** (each merchant has a fixed acquirer):30- `Belles_cookbook_store` → `US`31- `Crossfit_Hanna` → `NL` (majority) and `GB`32- `Golfclub_Baron_Friso` → `IT`33- `Martinis_Fine_Steakhouse` → `FR`34- `Rafa_AI` → `NL`3536## Month → day_of_year Mapping (2023, non-leap year)3738| Month | day_of_year range |39|-------|-------------------|40| January | 1–31 |41| February | 32–59 |42| March | 60–90 |43| April | 91–120 |44| May | 121–151 |45| June | 152–181 |46| July | 182–212 |47| August | 213–243 |48| September | 244–273 |49| October | 274–304 |50| November | 305–334 |51| December | 335–365 |5253Use `(df['day_of_year'] >= start) & (df['day_of_year'] <= end)` to filter date ranges.5455## Critical Filtering Rules5657### Card scheme is a filter column, not part of the merchant name58When a question says **"Merchant_X's TransactPlus transactions"**, it means:59```python60df[(df['merchant'] == 'Merchant_X') & (df['card_scheme'] == 'TransactPlus')]61```62Never omit the `card_scheme` filter when a card scheme is mentioned in the question.6364### Multi-month ranges65"Between January and April" means months January through April inclusive (day_of_year 1–120). Include both endpoint months.6667## Standard Solution Pattern6869```python70import pandas as pd7172df = pd.read_csv('/path/to/payments.csv')7374# 1. Apply all filters the question specifies75mask = pd.Series([True] * len(df), index=df.index)7677# Optional: filter by merchant78mask &= (df['merchant'] == 'Merchant_Name')7980# Optional: filter by card scheme81mask &= (df['card_scheme'] == 'CardSchemeName')8283# Optional: filter by date range84mask &= (df['day_of_year'] >= DAY_START) & (df['day_of_year'] <= DAY_END)8586filtered = df[mask]8788# 2. Group by the specified column and compute mean eur_amount89result = filtered.groupby('grouping_column')['eur_amount'].mean()9091# 3. Round to 2 decimal places (unless question specifies otherwise)92result = result.round(2)9394# 4. Sort ascending by value95result = result.sort_values(ascending=True)9697# 5. Format as list of strings98answer = [f"{idx}: {val}" for idx, val in result.items()]99print(answer)100```101102## Output Format103104- **List of grouped averages**: `['GroupA: 71.18', 'GroupB: 86.79', ...]`105 - Sorted in **ascending order** by amount106 - Amounts rounded to **2 decimal places**107 - Use the grouping key exactly as it appears in the data (e.g., `FR`, `SE`, `Ecommerce`)108- **Single scalar average**: return as a number (e.g., `90.696`)109110## Interpreting "Average per Unique X"111112When the question asks for "average transaction amount per unique email/card/customer":113- Compute the mean per entity, then take the mean of those per-entity averages:114 ```python115 result = df.groupby('email_address')['eur_amount'].mean().mean()116 ```117- This differs from `total_amount / count_of_unique_entities` (which gives a wrong result).118119## Common Mistakes to Avoid1201211. **Wrong acquirer_country values**: acquirer_country is `FR, GB, IT, NL, US` — not the same as issuing_country (`BE, ES, FR, GR, IT, LU, NL, SE`).1222. **Missing card_scheme filter**: "NexPay transactions" = `card_scheme == 'NexPay'`, not just merchant filter.1233. **Wrong date range**: Verify month boundaries from the table. September–October is days 244–304.1244. **Sorting direction**: Always sort **ascending** by `eur_amount` unless the question says descending.1255. **Rounding display**: Use `f"{val:.2f}"` to show trailing zeros when formatting strings.1266. **NaN in email_address**: `groupby` automatically excludes NaN keys — no need to drop them explicitly.