Project Python Foundations: FoodHub Data Analysis¶
Context¶
The number of restaurants in New York is increasing day by day. Lots of students and busy professionals rely on those restaurants due to their hectic lifestyles. Online food delivery service is a great option for them. It provides them with good food from their favorite restaurants. A food aggregator company FoodHub offers access to multiple restaurants through a single smartphone app.
The app allows the restaurants to receive a direct online order from a customer. The app assigns a delivery person from the company to pick up the order after it is confirmed by the restaurant. The delivery person then uses the map to reach the restaurant and waits for the food package. Once the food package is handed over to the delivery person, he/she confirms the pick-up in the app and travels to the customer's location to deliver the food. The delivery person confirms the drop-off in the app after delivering the food package to the customer. The customer can rate the order in the app. The food aggregator earns money by collecting a fixed margin of the delivery order from the restaurants.
Objective¶
The food aggregator company has stored the data of the different orders made by the registered customers in their online portal. They want to analyze the data to get a fair idea about the demand of different restaurants which will help them in enhancing their customer experience. Suppose you are hired as a Data Scientist in this company and the Data Science team has shared some of the key questions that need to be answered. Perform the data analysis to find answers to these questions that will help the company to improve the business.
Data Description¶
The data contains the different data related to a food order. The detailed data dictionary is given below.
Data Dictionary¶
- order_id: Unique ID of the order
- customer_id: ID of the customer who ordered the food
- restaurant_name: Name of the restaurant
- cuisine_type: Cuisine ordered by the customer
- cost_of_the_order: Cost of the order
- day_of_the_week: Indicates whether the order is placed on a weekday or weekend (The weekday is from Monday to Friday and the weekend is Saturday and Sunday)
- rating: Rating given by the customer out of 5
- food_preparation_time: Time (in minutes) taken by the restaurant to prepare the food. This is calculated by taking the difference between the timestamps of the restaurant's order confirmation and the delivery person's pick-up confirmation.
- delivery_time: Time (in minutes) taken by the delivery person to deliver the food package. This is calculated by taking the difference between the timestamps of the delivery person's pick-up confirmation and drop-off information
Let us start by importing the required libraries¶
# Installing the libraries with the specified version.
!pip install numpy==1.25.2 pandas==1.5.3 matplotlib==3.7.1 seaborn==0.13.1 -q --user
Note: After running the above cell, kindly restart the notebook kernel and run all cells sequentially from the start again.
# import libraries for data manipulation
import numpy as np
import pandas as pd
# import libraries for data visualization
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.simplefilter('ignore')
%matplotlib inline
pd.set_option('display.float_format', lambda x: '%.2f' % x)
sns.set_palette("ocean_r")
Understanding the structure of the data¶
df= pd.read_csv('foodhub_order.csv')
df.columns
Index(['order_id', 'customer_id', 'restaurant_name', 'cuisine_type',
'cost_of_the_order', 'day_of_the_week', 'rating',
'food_preparation_time', 'delivery_time'],
dtype='object')
df.head()
| order_id | customer_id | restaurant_name | cuisine_type | cost_of_the_order | day_of_the_week | rating | food_preparation_time | delivery_time | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1477147 | 337525 | Hangawi | Korean | 30.75 | Weekend | Not given | 25 | 20 |
| 1 | 1477685 | 358141 | Blue Ribbon Sushi Izakaya | Japanese | 12.08 | Weekend | Not given | 25 | 23 |
| 2 | 1477070 | 66393 | Cafe Habana | Mexican | 12.23 | Weekday | 5 | 23 | 28 |
| 3 | 1477334 | 106968 | Blue Ribbon Fried Chicken | American | 29.20 | Weekend | 3 | 25 | 15 |
| 4 | 1478249 | 76942 | Dirty Bird to Go | American | 11.59 | Weekday | 4 | 25 | 24 |
Question 1: How many rows and columns are present in the data? [0.5 mark]¶
df.shape
(1898, 9)
Observations:¶
- This data set has 1898 rows or 9 columns.
Question 2: What are the datatypes of the different columns in the dataset? (The info() function can be used) [0.5 mark]¶
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1898 entries, 0 to 1897 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 order_id 1898 non-null int64 1 customer_id 1898 non-null int64 2 restaurant_name 1898 non-null object 3 cuisine_type 1898 non-null object 4 cost_of_the_order 1898 non-null float64 5 day_of_the_week 1898 non-null object 6 rating 1898 non-null object 7 food_preparation_time 1898 non-null int64 8 delivery_time 1898 non-null int64 dtypes: float64(1), int64(4), object(4) memory usage: 133.6+ KB
Observations:¶
- This data set has 3 data types, integers (int64), floats (float64) and objects. Rating column has a type of object but integer is expected.
Question 3: Are there any missing values in the data? If yes, treat them using an appropriate method. [1 mark]¶
df.isnull().sum()
order_id 0 customer_id 0 restaurant_name 0 cuisine_type 0 cost_of_the_order 0 day_of_the_week 0 rating 0 food_preparation_time 0 delivery_time 0 dtype: int64
Observations:¶
- There are no missing values.
Question 4: Check the statistical summary of the data. What is the minimum, average, and maximum time it takes for food to be prepared once an order is placed? [2 marks]¶
df.describe().T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| order_id | 1898.00 | 1477495.50 | 548.05 | 1476547.00 | 1477021.25 | 1477495.50 | 1477969.75 | 1478444.00 |
| customer_id | 1898.00 | 171168.48 | 113698.14 | 1311.00 | 77787.75 | 128600.00 | 270525.00 | 405334.00 |
| cost_of_the_order | 1898.00 | 16.50 | 7.48 | 4.47 | 12.08 | 14.14 | 22.30 | 35.41 |
| food_preparation_time | 1898.00 | 27.37 | 4.63 | 20.00 | 23.00 | 27.00 | 31.00 | 35.00 |
| delivery_time | 1898.00 | 24.16 | 4.97 | 15.00 | 20.00 | 25.00 | 28.00 | 33.00 |
Observations:¶
- The average cost of an order is $16.50.
- The average prep time is about 27 minutes.
- The average delivery time is about 24 minues.
- The order_id and customer_id values are nominal values for which the central tendancies calculations are meaningless and should be ignored.
Question 5: How many orders are not rated? [1 mark]¶
df['rating'].value_counts()
Not given 736 5 588 4 386 3 188 Name: rating, dtype: int64
Exploratory Data Analysis (EDA)¶
Observations:¶
- There are 736 orders that are not rated which is indicated by the value 'Not Given'. The nature of a subjective rating makes it not a good candidate for imputing data however the 'Not Given' could be changed to NaN instead of the string or we may also exclude those rows from analysis. Consideration should be given for analysis of this column so that the missing data doesn't result in an inaccurate representation of a particular restaraunt, cuisine, customer, day of the week etc. We should avoid substituing zero or integer value for missing ratings.
Univariate Analysis¶
Question 6: Explore all the variables and provide observations on their distributions. (Generally, histograms, boxplots, countplots, etc. are used for univariate exploration.) [9 marks]¶
df['customer_id'].nunique()
1200
df['restaurant_name'].nunique()
178
df['cuisine_type'].nunique()
14
df['cost_of_the_order'].agg(['median','mean'])
median 14.14 mean 16.50 Name: cost_of_the_order, dtype: float64
plt.figure(figsize=(10, 5))
sns.histplot(data=df,x='cost_of_the_order', kde=True)
plt.title('Distribution of Cost of Orders')
plt.xlabel('Cost of the Order')
plt.ylabel('Frequency')
plt.show()
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, x='cost_of_the_order')
plt.title('Boxplot of Cost of Orders')
plt.xlabel('Cost of the Order')
plt.ylabel('Cost')
plt.show()
Observations:¶
- The cost data is multi modal with peaks around $12, $25, $30 and right skewed.
- The median is about $14.
plt.figure(figsize=(10, 5))
sns.histplot(data=df,x='delivery_time', kde=True)
plt.title('Distribution of Delivery Time')
plt.xlabel('Delivery Time (minutes)')
plt.ylabel('Frequency')
plt.show()
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, x='delivery_time')
plt.title('Boxplot of Delivery Time')
plt.xlabel('Delivery Time')
plt.ylabel('Delivery Time (minutes)')
plt.show()
Observations:¶
- Delivery times are between 15-32 minutes with a median around 25 minutes.
- Even fairly normal distribution.
plt.figure(figsize=(10, 5))
sns.histplot(data=df, x='food_preparation_time', kde=True)
plt.title('Distribution of Food Preparation Time')
plt.xlabel('Food Preparation Time (minutes)')
plt.ylabel('Frequency')
plt.show()
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, x='food_preparation_time')
plt.title('Boxplot of Food Preparation Time')
plt.xlabel('Food Preparation Time')
plt.ylabel('Food Preparation Time (minutes)')
plt.show()
Observations:¶
- Food preperation time takes from 20-35 minutes and has a median delivery time around 27 minutes with is a little longer than delivery time.
- Minimum prep time is longer than delivery time.
- By taking the min/max prep time and delivery time I can see that it will take at least 35 minutes from time of order but can be as up to hour and and 15 minutes.
plt.figure(figsize=(15, 5))
sns.countplot(data=df, x='cuisine_type', order=df['cuisine_type'].value_counts().index)
plt.title('Count of Orders by Cuisine Type')
plt.xlabel('Cuisine Type')
plt.ylabel('Count')
plt.xticks(rotation=45)
plt.show()
plt.figure(figsize=(10, 5))
sns.countplot(data=df, x='rating')
plt.title('Count of Ratings')
plt.xlabel('Rating')
plt.ylabel('Count')
plt.show()
plt.figure(figsize=(10, 5))
sns.countplot(data=df, x='day_of_the_week')
plt.title('Count of Orders by Day of the Week')
plt.xlabel('Day of the Week')
plt.ylabel('Count')
plt.show()
Observations:¶
- The most popular cuisines are American, Japanese and Italian by a significant margin.
- There are are a significant number of missing ratings. Almost 1/3 of orders don't provide a rating.
- The 2 day weekend has more than double the number of orders as the 5 weekdays combined.
Question 7: Which are the top 5 restaurants in terms of the number of orders received? [1 mark]¶
top_5_restaurants = df['restaurant_name'].value_counts().head().reset_index()
top_5_restaurants.columns = ['restaurant_name', 'count']
print('The top 5 restaurants in terms of the number of orders received:')
print(top_5_restaurants.to_string(index=False))
sns.catplot(data=top_5_restaurants, x='restaurant_name', y='count', kind='bar')
plt.xticks(rotation=45)
plt.title('Top 5 Restaurants by Order Count')
plt.xlabel('Restaurant Name')
plt.ylabel('Order Count')
plt.show()
The top 5 restaurants in terms of the number of orders received:
restaurant_name count
Shake Shack 219
The Meatball Shop 132
Blue Ribbon Sushi 119
Blue Ribbon Fried Chicken 96
Parm 68
Observations:¶
Shake Shake has the largest number of order by almost double the next largest.
Observations:¶
Question 8: Which is the most popular cuisine on weekends? [1 mark]¶
popular_on_weekend = df['cuisine_type'].where(df['day_of_the_week'] == 'Weekend').value_counts().head().reset_index()
popular_on_weekend.columns = ['cuisine_type', 'count']
print('The most popular cuisines on weekends are:')
print(popular_on_weekend.to_string(index=False))
sns.catplot(data=popular_on_weekend, x='cuisine_type', y='count', kind='bar')
plt.title('Popular Cuisine Types on Weekends')
plt.xlabel('Cuisine Type')
plt.ylabel('Count')
plt.show()
The most popular cuisines on weekends are:
cuisine_type count
American 415
Japanese 335
Italian 207
Chinese 163
Mexican 53
Observations:¶
- The most popular cuisines on the weekend is American, Japanese and Italian.
Question 9: What percentage of the orders cost more than 20 dollars? [2 marks]¶
percent_cost_above_20_dollars = df[df['cost_of_the_order'] > 20]['order_id'].count() / df.shape[0] * 100
print(f'Percentage of the orders cost more than 20 dollars: {percent_cost_above_20_dollars:.2f}%')
Percentage of the orders cost more than 20 dollars: 29.24%
Observations:¶
- About a 1/3 of the orders are over $20.
Question 10: What is the mean order delivery time? [1 mark]¶
mean_delivery_time = df['delivery_time'].mean()
print(f'The mean order delivery time: {mean_delivery_time:.2f}')
The mean order delivery time: 24.16
Observations:¶
- The average deliver time is about 24 minutes which is a little lower than the median which tells us the data is a little bit left skewed with some orders getting delivered very fast.
Question 11: The company has decided to give 20% discount vouchers to the top 3 most frequent customers. Find the IDs of these customers and the number of orders they placed. [1 mark]¶
top_3_customers = df['customer_id'].value_counts().head(3)
print(f'The top 3 customers by number of orders placed:')
print(top_3_customers)
The top 3 customers by number of orders placed: 52832 13 47440 10 83287 9 Name: customer_id, dtype: int64
Observations:¶
- The top customer placed 13 orders, 2nd placed 10 orders, 3rd placed 9 orders.
Multivariate Analysis¶
Question 12: Perform a multivariate analysis to explore relationships between the important variables in the dataset. (It is a good idea to explore relations between numerical variables as well as relations between numerical and categorical variables) [10 marks]¶
plt.figure(figsize=(15, 5))
sns.countplot(data=df, x='cuisine_type', order=df['cuisine_type'].value_counts().index, hue='day_of_the_week', palette='ocean_r')
plt.xticks(rotation=45)
plt.title('Count of Cuisine Types by Day of the Week')
plt.xlabel('Cuisine Type')
plt.ylabel('Count')
plt.show()
Observations:¶
- The most popular restaurants are the same for weekdays and weekends.
plt.figure(figsize=(10, 5))
sns.histplot(data=df, x='cost_of_the_order', hue='day_of_the_week', kde=True, palette='ocean_r')
plt.title('Distribution of Cost of Orders by Day of the Week')
plt.xlabel('Cost of the Order')
plt.ylabel('Frequency')
plt.show()
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, x='day_of_the_week', y='cost_of_the_order', hue='day_of_the_week', palette='ocean_r')
plt.title('Boxplot of Cost of Orders by Day of the Week')
plt.xlabel('Day of the Week')
plt.ylabel('Cost of the Order')
plt.show()
Observations:¶
- The cost of an order is not impacted by weekday or weekend.
plt.figure(figsize=(10, 5))
plt.hist(df[['delivery_time', 'food_preparation_time']].values, bins=20, alpha=0.7, label=['Delivery Time', 'Food Preparation Time'])
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.title('Histogram of Delivery Time and Food Preparation Time')
plt.legend()
plt.show()
Observations:¶
- The preperation time is longer than delivery time.
df['total_time'] = df['food_preparation_time'] + df['delivery_time']
rating_order = [3, 4, 5, 'Not given']
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, y='rating', x='total_time', hue='day_of_the_week', order=rating_order)
plt.title('Boxplot of Rating vs Total Time')
plt.xlabel('Total Time (minutes)')
plt.ylabel('Rating')
plt.show()
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, y='cuisine_type', x='total_time', hue='day_of_the_week')
plt.title('Boxplot of Cuisine Type vs Total Time')
plt.xlabel('Total Time (minutes)')
plt.ylabel('Cuisine Type')
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, y='cuisine_type', x='cost_of_the_order', hue='day_of_the_week')
plt.title('Boxplot of Cuisine Type vs Cost of the Order')
plt.xlabel('Cost of the Order')
plt.ylabel('Cuisine Type')
plt.show()
Observations:¶
- The ratings are not significantly different on the weekend vs weekday or by total time.
- Total time is significantly longer on the weekends.
- Korean seems to have a little less variability and seems to have a signifcantly faster total time.
- Vietnamese food has a significantly lower cost per order.
- French and Middle easter have medians over $20 on weekdays.
- French and Thai have the highest median for weekdays.
df_long = pd.melt(df, id_vars='day_of_the_week', value_vars=['food_preparation_time', 'delivery_time', 'total_time'],
var_name='time_type', value_name='time')
plt.figure(figsize=(10, 5))
sns.boxplot(data=df_long, y='time_type', x='time', hue='day_of_the_week')
plt.title('Boxplot of Time Type vs Time')
plt.xlabel('Time (minutes)')
plt.ylabel('Time Type')
plt.show()
Observations:¶
- Prep time is not impacted by the day of the week but delivery time is.
- The significanlty longer total time on the week seems directly related the longer delivery time.
Question 13: The company wants to provide a promotional offer in the advertisement of the restaurants. The condition to get the offer is that the restaurants must have a rating count of more than 50 and the average rating should be greater than 4. Find the restaurants fulfilling the criteria to get the promotional offer. [3 marks]¶
df_filtered = df[df['rating'] != 'Not given'].copy()
df_filtered['rating'] = df_filtered['rating'].astype('int')
aggregated_df = df_filtered.groupby('restaurant_name').agg(count=('rating', 'size'),mean=('rating', 'mean')).reset_index()
elgible = aggregated_df[(aggregated_df['count'] > 50) & (aggregated_df['mean'] > 4)]
elgible.sort_values(by='count', ascending = False, inplace=True)
print(elgible.to_string(index=False))
restaurant_name count mean
Shake Shack 133 4.28
The Meatball Shop 84 4.51
Blue Ribbon Sushi 73 4.22
Blue Ribbon Fried Chicken 64 4.33
Observations:¶
- Shake Shack also has the highest number of ratings.
- The Meatball Shop has the highest mean of the top.
- Of the restaurants that are elgible for offer all of them are in the top 5 restuarants by order count
Question 14: The company charges the restaurant 25% on the orders having cost greater than 20 dollars and 15% on the orders having cost greater than 5 dollars. Find the net revenue generated by the company across all orders. [3 marks]¶
df['revenue'] = df['cost_of_the_order'].apply(lambda x: x * 0.25 if x > 20 else (x * 0.15 if x > 5 else 0))
print(df[['restaurant_name', 'cost_of_the_order', 'revenue']].sort_values(by='revenue', ascending=False).head(5).to_string(index=False))
print('Total revenue from all restaurants: ', df.revenue.sum())
restaurant_name cost_of_the_order revenue
Pylos 35.41 8.85
Han Dynasty 34.19 8.55
Blue Ribbon Sushi 33.37 8.34
Nobu Next Door 33.37 8.34
Tres Carnes 33.32 8.33
Total revenue from all restaurants: 6166.303
Observations:¶
- The total revenue from all restaurants is $6166.30.
- The highest amount of revenue from one order was 8.85.
Question 15: The company wants to analyze the total time required to deliver the food. What percentage of orders take more than 60 minutes to get delivered from the time the order is placed? (The food has to be prepared and then delivered.) [2 marks]¶
df['total_time'] = df['food_preparation_time'] + df['delivery_time']
orders_more_than_60_min = df[df['total_time'] > 60]
percentage_more_than_60_min = (len(orders_more_than_60_min) / len(df)) * 100
print("Percentage of orders taking more than 60 minutes to deliver: {:.2f}%".format(percentage_more_than_60_min))
Percentage of orders taking more than 60 minutes to deliver: 10.54%
Observations:¶
- The percentage of orders taking more than 60 minutes to deliver: 10.54%
Question 16: The company wants to analyze the delivery time of the orders on weekdays and weekends. How does the mean delivery time vary during weekdays and weekends? [2 marks]¶
mean_delivery_time = df.groupby('day_of_the_week')['delivery_time'].mean()
print(mean_delivery_time)
day_of_the_week Weekday 28.34 Weekend 22.47 Name: delivery_time, dtype: float64
Observations:¶
- The delivery time increases on the weekdays.
total_revenue_by_restaurant = df.groupby('restaurant_name')['revenue'].sum()
total_revenue = total_revenue_by_restaurant.sum()
# Calculate percentage of revenue for each restaurant
percentage_revenue_by_restaurant = (total_revenue_by_restaurant / total_revenue) * 100
# Calculate mean total time by restaurant
mean_delivery_time_by_restaurant = df.groupby('restaurant_name')['delivery_time'].mean()
# Convert 'rating' column to numeric, replacing non-numeric values with NaN
df['rating'] = pd.to_numeric(df['rating'], errors='coerce')
# Filter out rows with NaN values in the 'rating' column
df_filtered = df.dropna(subset=['rating'])
# Calculate mean rating by restaurant
mean_rating_by_restaurant = df_filtered.groupby('restaurant_name')['rating'].mean()
# Create a DataFrame for the mean values
result_df = pd.DataFrame({
'revenue': total_revenue_by_restaurant,
'percent_revenue': percentage_revenue_by_restaurant,
'mean_delivery_time': mean_delivery_time_by_restaurant,
'mean_rating': mean_rating_by_restaurant
}).reset_index() # Reset index to make 'restaurant_name' a column
result_df = result_df.sort_values(by='percent_revenue', ascending=False)
print('Final DataFrame:')
print(result_df.head(10).to_string(index=False))
Final DataFrame:
restaurant_name revenue percent_revenue mean_delivery_time mean_rating
Shake Shack 703.61 11.41 24.66 4.28
The Meatball Shop 419.83 6.81 24.24 4.51
Blue Ribbon Sushi 360.46 5.85 23.94 4.22
Blue Ribbon Fried Chicken 340.20 5.52 24.15 4.33
Parm 218.56 3.54 25.50 4.13
RedFarm Broadway 191.47 3.11 23.15 4.24
RedFarm Hudson 180.93 2.93 24.20 4.18
TAO 167.36 2.71 23.16 4.36
Han Dynasty 149.40 2.42 23.15 4.43
Rubirosa 140.81 2.28 23.68 4.12
result_df = result_df.sort_values(by='percent_revenue', ascending=False).head(10)
fig, ax = plt.subplots(figsize=(12, 8))
sns.barplot(data=result_df, x='restaurant_name', y='percent_revenue', ax=ax, color='mediumseagreen')
ax.set_ylabel('Revenue')
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')
ax2 = ax.twinx()
sns.lineplot(data=result_df, x='restaurant_name', y='mean_rating', ax=ax2, marker='o', color='royalblue')
ax2.set_ylabel('Mean Rating')
ax3 = ax.twinx()
sns.lineplot(data=result_df, x='restaurant_name', y='mean_delivery_time', ax=ax3, marker='o', color='gold')
ax3.set_ylabel('Mean Delivery Time')
ax3.spines['right'].set_position(('outward', 60))
ax.set_title('Top 10 Restaurants: Percemt Revemue, Total Time, and Rating')
ax2.legend(['Mean Rating'], loc='upper right')
ax3.legend(['Mean Delivery Time'], loc='upper left')
plt.tight_layout()
plt.show()
pivot_df = df.pivot_table(index='cuisine_type', columns='day_of_the_week', values='revenue', aggfunc='sum')
pivot_df['total_revenue'] = pivot_df.sum(axis=1)
pivot_df = pivot_df.sort_values(by='total_revenue', ascending=False).head(10)
plt.figure(figsize=(10, 6))
sns.heatmap(pivot_df, annot=True, cmap='YlGnBu', fmt='.0f', linewidths=0.5)
plt.title('Revenue by Cuisine Type and Day of the Week')
plt.xlabel('Day of the Week')
plt.ylabel('Cuisine type')
plt.show()
pivot_df = df.pivot_table(index='restaurant_name', columns='day_of_the_week', values='revenue', aggfunc='sum')
pivot_df['total_revenue'] = pivot_df.sum(axis=1)
pivot_df = pivot_df.sort_values(by='total_revenue', ascending=False).head(10)
plt.figure(figsize=(10, 6))
sns.heatmap(pivot_df, annot=True, cmap='YlGnBu', fmt='.0f', linewidths=0.5)
plt.title('Revenue by Restaurant (top 10) and Day of the Week')
plt.xlabel('Day of the Week')
plt.ylabel('Restaurant')
plt.show()
correlation = df.corr()
sns.heatmap(correlation, annot=True, cmap="ocean_r");
plt.xticks(rotation=45)
plt.show()
plt.figure(figsize = (5,3))
sns.pairplot(data=df[['cost_of_the_order', 'food_preparation_time', 'delivery_time', 'rating', 'total_time', 'revenue']], palette='ocean_r', diag_kind="kde")
plt.show()
<Figure size 500x300 with 0 Axes>
Conclusion and Recommendations¶
Question 17: What are your conclusions from the analysis? What recommendations would you like to share to help improve the business? (You can use cuisine type and feedback ratings to drive your business recommendations.) [6 marks]¶
Conclusions:¶
- Deliver time on the weekdays is longer.
- Shake shack and The Meatball shop are the biggest revenue generators
- American and Japenese cuisine are the biggest revenue generators
- There are too many missing ratings
Recommendations:¶
- Give drivers incentive to work on weekdays to decrease weekday delivery time.
- Promote French and Middle easter on weekdays to increase revenue.
- Promote French, Southern and Thai on weekdays to increase revenue.
- Give customers incentives to complete the ratings to imporve data.
- Offer discounts on weekday orders to increase revenue during the week. This would also likely give additional incentive to drivers to want to deliver on weekdays which would likely result in faster delivery times. Faster delivery times would likey result in improved ratings.
- Offer incentives to customers for restaurants that have higher order averages and consequently offer higher revenue percentages.
- Offer incentives to customers to increase their order size.
- Look for more restaurants/cuisines styles like the most popular ones.