Mathew K Analytics

Lesson 55 · Market Research Analytics in Python

Exporting Analysis Results and Reports in Python for Market Research

In this lesson, we learn to save our customer analytics results and survey insights. Exporting insights is essential for sharing findings with teams,…

⬇ Download notebookOpen in Colab ↗

What you'll learn

Data

No separate download needed — the notebook creates or downloads everything it uses.

📓 Full notebook

Download .ipynb

Exporting Analysis Results and Reports#

  • In this lesson, we learn to save our customer analytics results and survey insights.
  • Exporting insights is essential for sharing findings with teams, management, or clients.
  • We demonstrate how to generate Excel, CSV, PDF, and text-based reports from real datasets.
  • By the end, you will know how to automate reporting and select the best formats for business impact.
import pandas as pd
import numpy as np
import openml
import warnings
warnings.filterwarnings('ignore')

Understanding Data Structures for Exporting Results#

  • Market research datasets often include survey responses, ratings, demographic fields, and text feedback.
  • Each column may represent a measure such as satisfaction, likelihood to recommend, or revenue.
  • Beginners sometimes export incomplete data, forget to anonymize, or mislabel summarized results.
  • Paying attention to data types and missing information is crucial to deliver reliable reports.
dataset = openml.datasets.get_dataset(42178)
df_cs, _, _, _ = dataset.get_data(dataset_format='dataframe')
print(df_cs.shape)
print(df_cs.head(3))
(7043, 20)
   gender  SeniorCitizen Partner Dependents  tenure PhoneService  \
0  Female              0     Yes         No       1           No   
1    Male              0      No         No      34          Yes   
2    Male              0      No         No       2          Yes   

      MultipleLines InternetService OnlineSecurity OnlineBackup  \
0  No phone service             DSL             No          Yes   
1                No             DSL            Yes           No   
2                No             DSL            Yes          Yes   

  DeviceProtection TechSupport StreamingTV StreamingMovies        Contract  \
0               No          No          No              No  Month-to-month   
1              Yes          No          No              No        One year   
2               No          No          No              No  Month-to-month   

  PaperlessBilling     PaymentMethod  MonthlyCharges TotalCharges Churn  
0              Yes  Electronic check           29.85        29.85    No  
1               No      Mailed check           56.95       1889.5    No  
2              Yes      Mailed check           53.85       108.15   Yes  
df_nps = pd.DataFrame({'CustomerID': range(1,501), 'Age': np.random.randint(18,70,500), 'Region': np.random.choice(['North','South','East','West'],500), 'NPS_Score': np.random.randint(0,11,500)})
print(df_nps.shape)
print(df_nps.head(3))
(500, 4)
   CustomerID  Age Region  NPS_Score
0           1   65   West          1
1           2   57   East          7
2           3   48  North          3
summary = df_cs[['gender','SeniorCitizen','tenure','MonthlyCharges','TotalCharges','Churn']].describe(include='all')
print(summary)
       gender  SeniorCitizen       tenure  MonthlyCharges TotalCharges Churn
count    7043    7043.000000  7043.000000     7043.000000         7043  7043
unique      2            NaN          NaN             NaN         6531     2
top      Male            NaN          NaN             NaN         20.2    No
freq     3555            NaN          NaN             NaN           11  5174
mean      NaN       0.162147    32.371149       64.761692          NaN   NaN
std       NaN       0.368612    24.559481       30.090047          NaN   NaN
min       NaN       0.000000     0.000000       18.250000          NaN   NaN
25%       NaN       0.000000     9.000000       35.500000          NaN   NaN
50%       NaN       0.000000    29.000000       70.350000          NaN   NaN
75%       NaN       0.000000    55.000000       89.850000          NaN   NaN
max       NaN       1.000000    72.000000      118.750000          NaN   NaN
summary.to_csv('customer_summary.csv')
nps_grouped = df_nps.groupby('Region')['NPS_Score'].mean().reset_index()
print(nps_grouped)
  Region  NPS_Score
0   East   5.303226
1  North   5.973451
2  South   5.067797
3   West   4.894737
nps_grouped.to_excel('regional_nps_report.xlsx', index=False)
# Text-based insights for lightweight sharing
with open('key_metrics.txt', 'w') as f:
    f.write('Key Customer Metrics\n')
    f.write(f'Total Customers: {df_cs.shape[0]}\n')
    f.write(f'Churn Rate: {df_cs["Churn"].value_counts(normalize=True).to_dict()}\n')
print('Text report saved.')
Text report saved.
# Handling missing survey responses before export
missing = df_cs.isna().sum()
print(missing)
df_cs_clean = df_cs.dropna()
gender              0
SeniorCitizen       0
Partner             0
Dependents          0
tenure              0
PhoneService        0
MultipleLines       0
InternetService     0
OnlineSecurity      0
OnlineBackup        0
DeviceProtection    0
TechSupport         0
StreamingTV         0
StreamingMovies     0
Contract            0
PaperlessBilling    0
PaymentMethod       0
MonthlyCharges      0
TotalCharges        0
Churn               0
dtype: int64
# Export cleaned data for downstream analysis
df_cs_clean.to_csv('clean_customer_survey.csv', index=False)
# Exporting selected columns only (privacy, focus)
selected = df_cs[['gender','MonthlyCharges','Churn']]
selected.to_csv('selected_columns_survey.csv', index=False)
# Exporting to Excel with multiple sheets (advanced)
with pd.ExcelWriter('multi_report.xlsx') as writer:
    summary.to_excel(writer, sheet_name='Summary')
    nps_grouped.to_excel(writer, sheet_name='NPS_by_Region')
# Exporting with open-ended text feedback
feedback_df = pd.DataFrame({'CustomerID':[1,2,3,4,5], 'Feedback':[
    'Great service and friendly staff',
    'Delivery was slow and packaging was poor',
    'Excellent quality, will buy again',
    'Customer support needs improvement',
    'Good value for money']
})
feedback_df.to_csv('customer_feedback.csv', index=False)
# Marketing campaign export example
dataset = openml.datasets.get_dataset(1461)
df_mkt, _, _, _ = dataset.get_data(dataset_format='dataframe')
df_mkt.columns = ['age','job','marital','education','default','balance','housing','loan','contact','day','month','duration','campaign','pdays','previous','poutcome','response']
df_mkt.to_excel('marketing_campaign.xlsx', index=False)
# Errorincorrect groupby: mistyped field
try:
    bad_group = df_cs.groupby('Gendre')['MonthlyCharges'].mean()
except Exception as e:
    print('Error:', e)
Error: 'Gendre'
# Errormisinterpreted Likert/NPS scales: mean instead of %
nps_pct = (df_nps['NPS_Score'] >= 9).mean()
print(f'Pct Promoters (score 9 or 10): {nps_pct:.2%}')
Pct Promoters (score 9 or 10): 20.80%
# Best practice: Export cross-tabs of churn by gender
churn_ct = pd.crosstab(df_cs['gender'], df_cs['Churn'])
print(churn_ct)
churn_ct.to_csv('churn_xtab.csv')
Churn     No  Yes
gender           
Female  2549  939
Male    2625  930
# Trend analysis: Monthly new customer count
dates = pd.date_range('2021-01-01', periods=24, freq='M')
cohort_df = pd.DataFrame({'CustomerID': np.random.randint(1000,2000,len(dates)), 'Signup_Month': dates, 'Active_Users': np.random.randint(50,300,len(dates))})
monthly_counts = cohort_df.groupby(cohort_df['Signup_Month'].dt.to_period('M'))['Active_Users'].sum().reset_index()
monthly_counts.to_csv('monthly_new_users.csv', index=False)
print(monthly_counts.head())
  Signup_Month  Active_Users
0      2021-01           239
1      2021-02           265
2      2021-03            82
3      2021-04            55
4      2021-05            74
# End-to-end: Exporting an actionable insight from survey data
avg_charge = df_cs['MonthlyCharges'].mean()
churn_rate = df_cs['Churn'].value_counts(normalize=True).get('Yes',0)
insight = f'Average monthly charge: ${avg_charge:.2f}\nChurn rate: {churn_rate:.2%}\nRecommendation: Focus retention efforts on high-churn segments with above-average charges.'
with open('actionable_insight.txt', 'w') as f:
    f.write(insight)
print(insight)
Average monthly charge: $64.76
Churn rate: 26.54%
Recommendation: Focus retention efforts on high-churn segments with above-average charges.

Recap: Best Reporting Practices in Market Research#

  • Check input data for missing and duplicate rows before export.
  • Use descriptive filenames and include dates or versions as needed.
  • Choose export formats by stakeholder: CSV for analysts, Excel for managers, text for quick sharing.
  • Add business context to every numberpercentages, totals, and groupings matter.
  • Document every assumption and transformation for auditability.
  • Keep exported tables and figures consistent with report wording.

Next Steps and Practice#

  • Try exporting summary tables for at least two different segments.
  • Practice exporting both quantitative and qualitative insights.
  • Watch our video guide on automating customer analytics reports on YouTube!

Found this useful?

All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.