上海餐饮数据分析与可视化

数据下载入口:Pandas+Pyecharts | 上海市餐饮数据分析可视化 - Heywhale.com

数据介绍

  • 类别:餐饮类别的名称(如烧烤、美食、粤菜等)
  • 行政区:餐厅所在行政区的名称(如浦东新区、闵行区等)
  • 点评数:该餐厅的点评数量
  • 口味环境服务:餐厅在这三个方面的评分
  • 人均消费:餐厅的人均消费
  • 城市:餐厅所在的城市(上海市)
  • LngLat:餐厅的经纬度

首先先读取数据:

import pandas as pd


# 尝试的编码格式列表
encodings_tried = ['utf-8', 'gbk', 'ISO-8859-1', 'latin1']

# 文件路径
file_path = '上海餐饮数据.csv'

# 尝试使用不同的编码格式读取文件
for encoding in encodings_tried:
    try:
        df = pd.read_csv(file_path, encoding=encoding)
        print(f"成功使用编码格式 {encoding} 读取文件")
        break  # 如果成功读取,则跳出循环
    except UnicodeDecodeError:
        print(f"编码格式 {encoding} 读取文件时发生错误")
        continue  # 如果发生错误,则尝试下一个编码

df

由于下载的csv文件不是utf-8编码,所以需要用其他编码读取方式进行读取,数据概览如下:

一:数据预处理

# 获取每一列的不同元素
for col in df.columns:
    unique_elements = df[col].unique()
    print(f"{col}列的不同元素: {unique_elements}")

首先观察每一列含有的元素如下:

可以发现“类别”,“行政区”列含有空值,且“口味”,“环境”,“服务”,“人均消费”列同时含有数字与文本。

# 删除“点评数”和“人均消费”列中含有 0 的行
df = df[(df['点评数']!= '0') & (df['人均消费']!= '0')]
# 去除每一列的空值
df = df.dropna(subset=['类别', '行政区', '点评数', '口味', '环境', '服务', '人均消费', '城市', 'Lng', 'Lat'])

首先去除数据的空值,然后只保留“口味”,“环境”,“服务”,“人均消费”列中的数字行。

# 定义一个函数来判断元素是否为数字
def is_numeric(value):
    try:
        float(value)
        return True
    except ValueError:
        return False

# 选择需要检查的列
columns_to_check = ['口味', '环境', '服务', '人均消费', 'Lng', 'Lat']

# 删除含有文本的行
df = df[df[columns_to_check].applymap(is_numeric).all(axis=1)]

二:数据可视化

1:各类别餐厅数量分布图

import matplotlib.pyplot as plt
# 设置Matplotlib的字体以支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

#  各类别餐厅的数量分布
category_counts = df['类别'].value_counts()

# 绘制柱状图
plt.figure(figsize=(10, 6))
category_counts.plot(kind='bar', color='skyblue')
plt.title('各类别餐厅数量分布')
plt.xlabel('类别')
plt.ylabel('数量')
plt.xticks(rotation=45)
plt.show()

首先绘制各类别餐厅数量分布图:

可以观测“甜点”,“快餐”,“咖厅”等快餐类餐厅数量较多。

2:各行政区餐厅数量分布

import matplotlib.pyplot as plt

# 设置 Matplotlib 的字体以支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 各行政区餐厅的数量分布
category_counts = df['行政区'].value_counts()

# 绘制饼形图
plt.figure(figsize=(10, 6))
plt.pie(category_counts, labels=category_counts.index, autopct='%1.1f%%')
plt.title('各行政区餐厅数量分布')
plt.show()

再绘制各行政区餐厅的数量分布图:

可以观测出浦东新区,闵行区,徐汇区,松江区,宝山区的数量相对多。

3:类别与行政区之间的相关性

from scipy.stats import chi2_contingency

# 创建交叉表
cross_tab = pd.crosstab(df['类别'], df['行政区'])

# 进行卡方检验
chi2, p, dof, expected = chi2_contingency(cross_tab)

print(f"卡方值:{chi2}")
print(f"p 值:{p}")

if p < 0.05:
    print("类别与行政区之间存在相关性")
else:
    print("类别与行政区之间不存在相关性")

根据结果求出卡方值较大,p值小于0.05,说明类别与行政区之间存在相关性。然后具体展示类别与行政区相关性的体现:

import seaborn as sns

# 创建交叉表
cross_tab = pd.crosstab(df['类别'], df['行政区'])

# 绘制热力图
plt.figure(figsize=(10, 8))
sns.heatmap(cross_tab, annot=True, fmt='d', cmap='YlGnBu')
plt.title('类别与行政区的相关性热力图')
plt.xlabel('行政区')
plt.ylabel('类别')
plt.show()

体现相关性的热力图如下:

4:不同类别的平均综合评分比较

import numpy as np


# 将"口味","服务","环境","人均消费"列的数据类型转换为数值型
df['口味'] = pd.to_numeric(df['口味'], errors='coerce')
df['服务'] = pd.to_numeric(df['服务'], errors='coerce')
df['环境'] = pd.to_numeric(df['环境'], errors='coerce')
df['人均消费'] = pd.to_numeric(df['人均消费'], errors='coerce')

# 提取相关列的数据
columns = ['口味', '服务', '环境', '人均消费']
data = df[columns].values

# 数据标准化
normalized_data = (data - np.min(data, axis=0)) / (np.max(data, axis=0) - np.min(data, axis=0))

# 计算熵值
k = 1 / np.log(data.shape[0])
entropy = -k * np.sum(normalized_data * np.log(normalized_data + 1e-5), axis=0)

# 计算权重
weight = (1 - entropy) / np.sum(1 - entropy)

# 计算综合评分
composite_score = np.dot(normalized_data, weight)

# 将综合评分添加到数据框中
df['综合评分'] = composite_score

首先使用熵权法得出每行数据的综合评分一列,然后整合得出不同类别的平均综合评分:

# 创建DataFrame
df1 = pd.DataFrame(data)

# 按照“类别”分组并计算综合评分平均值
category_avg_score = df.groupby('类别')['综合评分'].mean()

# 将结果从大到小排序并转换为DataFrame
sorted_df = category_avg_score.sort_values(ascending=False).reset_index()

sorted_df

排序后的前10类别的平均综合评分如下:

可以看出南菜,午茶,素菜的评分相对较高。

5:不同行政区的平均综合评分比较

# 创建DataFrame
df2 = pd.DataFrame(data)

# 按照“行政区”分组并计算综合评分平均值
category_avg_score = df.groupby('行政区')['综合评分'].mean()

# 将结果从大到小排序并转换为DataFrame
sorted_df2 = category_avg_score.sort_values(ascending=False).reset_index()

sorted_df2

同理得到排序后的前10行政区的平均综合评分如下:

可以看出静安区,卢湾区,徐汇区,浦东新区的餐厅平均综合评分较高。

想要探索多元化的数据分析视角,可以关注之前发布的相关内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值