Data Analytics Case Study

Cyclistic Bike-Share Analysis

Understanding how annual members and casual riders use Cyclistic bicycles differently

Python * Pandas * Data Cleaning * Exploratory Data Analysis * Matplotlib * Data Storytelling

This project analyzes Cyclistic bike-share trip data to identify meaningful differences between annual members and casual riders. The goal is to support marketing strategies that could encourage casual riders to become annual members.

Project Overview

Business Area

Bike-sharing and membership marketing

Target Users

Annual members and casual riders

Primary Goal

Identify opportunities to convert casual riders into annual members

Main Tools

Python, Pandas and Matplotlib

Business Problem

Cyclistic offers bicycles through annual memberships and single-ride or day-pass options. The company wants to understand how annual members and casual riders use the service differently.

Understanding these behavioural differences can help the marketing team design campaigns that are more relevant to casual riders and encourage them to purchase annual memberships.

Key Business Question

How do annual members and casual riders use Cyclistic bicycles differently?

Dataset

The analysis uses historical bike-share trip data containing individual ride records. Each row represents one bicycle trip and includes rider type, bicycle type, start time, end time and station information.

Rider Categories

Member and casual

Important Fields

Ride ID, rider type, bicycle type, start time, end time and station information

Calculated Fields

Ride length, weekday and additional time-based variables

Analysis Type

Descriptive and exploratory data analysis

Analytical Process

The analysis followed a structured approach from asking the right question to delivering actionable recommendations.

STEP 01

Ask

Defined the business problem and main analytical question.

STEP 02

Prepare

Imported and reviewed the bike-share datasets.

STEP 03

Process

Cleaned the data and created fields needed for analysis.

STEP 04

Analyze

Compared ride frequency and duration between members and casual riders.

STEP 05

Share

Created charts and communicated the main findings.

STEP 06

Act

Developed marketing recommendations from the evidence.

Behind the Analysis

This section connects the Python code to its analytical purpose, output and business value. Click each step to explore the complete workflow.

STEP 01 Import Libraries Pandas was used for data preparation and analysis, while Matplotlib and Seaborn supported visual exploration. +

Importing the Required Python Libraries

The Python environment was prepared by importing the libraries needed for data manipulation, numerical calculations and visualisation.

analysis.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
pd.set_option('display.max_columns', None)

Purpose

Import the tools needed to load, clean, transform, analyse and visualise the Cyclistic trip data.

Why It Matters

Pandas manages the dataset, NumPy supports numerical operations, and Matplotlib and Seaborn create charts.

Business Value

These libraries provide the analytical foundation needed to transform raw trip records into meaningful business insights.

Python libraries imported for the Cyclistic analysis
Python environment prepared for the Cyclistic analysis.
STEP 02 Load the Data Monthly trip files were loaded and combined into one Pandas DataFrame. +

Loading and Combining the Monthly Datasets

Multiple monthly CSV files were loaded and combined into one complete DataFrame for the analysis period.

load_data.py
import glob

files = sorted(
    glob.glob(
        "/kaggle/input/datasets/ashwinraphel/"
        "cycle-new-data-set/2025*.csv"
    )
)

df_list = []

for file in files:
    temp_df = pd.read_csv(file)
    df_list.append(temp_df)

df = pd.concat(df_list, ignore_index=True)

print(df.shape)
Original Records 5,552,092
Original Columns 13
Cyclistic monthly datasets loaded and combined
Twelve monthly CSV files were combined into one analytical dataset.
STEP 03 Explore the Dataset Dataset size, columns, data types, missing values and sample records were inspected. +

Understanding the Dataset Structure

The dataset was inspected before cleaning to understand its structure, quality and overall characteristics.

explore_data.py
df.shape
df.head()
df.info()
df.isnull().sum().sort_values(ascending=False)

Dataset size

The dataset size was checked to confirm the total number of rows and columns.

Column names

Column names were reviewed to understand the available dataset fields.

Data types

Data types were inspected to confirm that each column used an appropriate format.

Missing values

Missing values were identified before beginning the cleaning process.

Sample records

Sample records were reviewed to understand the dataset content and structure.

Sample Records

First five rows of the Cyclistic dataset
The first five rows verified that the dataset loaded correctly.

Dataset Structure

Cyclistic dataset structure and data types
Dataset structure showing column names and data types.

Missing Values

Missing values in the Cyclistic dataset
Missing values were concentrated mainly in station-related columns.
STEP 04 Clean and Prepare Data types and invalid ride durations were corrected, while relevant missing station values were reviewed and retained. +

Data Cleaning and Preparation

The data was cleaned to ensure that comparisons and visualisations were based on valid and consistent records.

clean_data.py
df['started_at'] = pd.to_datetime(
    df['started_at']
)

df['ended_at'] = pd.to_datetime(
    df['ended_at']
)

df['ride_length'] = (
    df['ended_at'] - df['started_at']
).dt.total_seconds() / 60

df = df[df['ride_length'] > 0]
df = df[df['ride_length'] <= 1440]
01

Convert Timestamps

Start and end times were converted from text into datetime values.

02

Calculate Duration

Ride duration was calculated in minutes.

03

Remove Invalid Rides

Negative, zero-length and rides longer than 24 hours were removed.

04

Retain Relevant Records

Missing station records were retained because they did not affect the main business question.

Cyclistic timestamp conversion
Timestamp columns converted into datetime values.
Final cleaned Cyclistic dataset size
Final dataset size after invalid records were removed.
STEP 05 Engineer Features Ride length, weekday, month, hour and weekend variables were created. +

Creating New Analytical Features

New variables were created from the timestamps to support deeper behavioural comparisons.

feature_engineering.py
df['ride_length'] = (
    df['ended_at'] - df['started_at']
).dt.total_seconds() / 60

df['day_of_week'] = (
    df['started_at'].dt.day_name()
)

df['month'] = (
    df['started_at'].dt.month_name()
)

df['hour'] = (
    df['started_at'].dt.hour
)

df['is_weekend'] = (
    df['day_of_week'].isin(
        ['Saturday', 'Sunday']
    )
)

Ride Length

Measures trip duration in minutes.

Day of Week

Supports comparisons across different weekdays.

Month

Supports seasonal and monthly trend analysis.

Hour

Supports time-of-day usage analysis.

Weekend

Distinguishes weekday rides from weekend rides.

Cyclistic engineered features
Dataset after creating the new analytical variables.
STEP 06 Analyse Behaviour Members and casual riders were compared using counts, averages, grouped summaries and visualisations. +

Comparing Member and Casual Rider Behaviour

Rider groups were compared across ride frequency, duration, weekday activity, monthly trends and bike preferences.

Ride Count by Rider Type

Cyclistic ride count by rider type
Observation

Members completed approximately 3.55 million rides, compared with approximately 2 million casual rides.

Business Insight

Members demonstrate more frequent usage and form Cyclistic's core customer group.

Average Ride Duration

Average Cyclistic ride duration
Observation

Casual rides averaged around 19.1 minutes, compared with 12 minutes for members.

Business Insight

Casual riders appear more likely to use bikes for recreation and leisure.

Usage by Weekday

Cyclistic usage by weekday

Monthly Ride Trends

Cyclistic monthly ride trends

Weekend vs Weekday Patterns

Cyclistic weekend and weekday patterns

Bike-Type Preferences

Cyclistic bike type preferences

Visualizations

Each visualization connects the Python analysis to a clear observation and a practical business insight.

01

Ride Count by Rider Type

Compares the total number of rides completed by annual members and casual riders.

02

Average Ride Duration

Shows how average trip length differs between members and casual riders.

03

Usage by Weekday

Identifies how rider activity changes across the days of the week.

04

Monthly Ride Trends

Highlights seasonal demand patterns and monthly changes in ride activity.

05

Weekday vs Weekend Usage

Compares ride activity on working days and weekends to reveal commuting and leisure patterns.

06

Bike-Type Preferences

Compares the bicycle types selected by members and casual riders.

Key Findings

The analysis revealed important differences in how members and casual riders use Cyclistic bicycles.

Casual riders take longer rides.

Casual riders had a higher average ride duration than annual members.

Members generate more total rides.

Annual members used the service more frequently, indicating regular and repeated usage.

Usage patterns suggest different purposes.

Members appear more likely to use bicycles for routine transport, while casual riders appear more likely to ride for leisure.

Time-based marketing is important.

Differences by day and time can help Cyclistic target campaigns more effectively.

Business Recommendations

Based on the rider behaviour analysis, the following recommendations can help Cyclistic increase annual memberships and improve customer engagement.

01

Promote Memberships During Leisure Periods

Target casual riders during weekends and periods of high recreational usage, when they are most engaged with the service.

02

Highlight Long-Term Cost Savings

Demonstrate how an annual membership can reduce long-term riding costs for frequent casual riders through targeted pricing messages.

03

Offer Trial Membership Incentives

Encourage conversion by providing limited-time discounts, free trial memberships, or promotional offers to riders with repeated casual usage.

04

Launch Targeted Digital Campaigns

Personalize marketing campaigns using rider behaviour, preferred riding periods, seasonal demand, and bicycle usage patterns to improve conversion rates.

Skills Demonstrated

Python Pandas Data Cleaning Feature Engineering Exploratory Data Analysis (EDA) Data Visualization Business Analysis Data Storytelling Business Recommendations