学习笔记(34):matplotlib绘制图表-房价数据分析与可视化

分析房价分布情况,通过直方图、核密度估计和正态分布拟合来直观展示房价的分布特征,并进行统计检验。

一、房价数据分析与可视化,代码分析

1.1、导入必要的库

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats
import os

  • 导入数据处理 (pandas)、绘图 (matplotlib, seaborn)库
  • 导入数学计算 (numpy, scipy) 和文件操作 (os) 库

1.2、设置中文字体和负号显示

# 设置 Windows 系统的中文字体
plt.rcParams["font.family"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

  • 设置了适用于 Windows 系统的中文字体,确保图表中的中文能正常显示
  • 解决了负号显示为方块的问题

1.3、数据加载函数 load_data()

def load_data(file_path):"""加载房价数据"""try:# 尝试读取CSV文件data = pd.read_csv(file_path)print(f"数据加载成功,共{data.shape[0]}条记录,{data.shape[1]}个特征")print(f"数据特征: {', '.join(data.columns.tolist())}")return dataexcept FileNotFoundError:print(f"错误: 文件 '{file_path}' 不存在")# 创建示例数据用于演示print("创建示例数据用于演示...")np.random.seed(42)size = 500data = pd.DataFrame({'price': np.random.normal(15000, 3000, size),  # 房价,单位:万元'area': np.random.normal(100, 20, size),  # 面积,单位:平方米'age': np.random.randint(1, 30, size),  # 房龄,单位:年})# 确保房价与面积正相关,与房龄负相关data['price'] = data['price'] + 50 * data['area'] - 100 * data['age']data['price'] = data['price'].clip(lower=5000)  # 设置价格下限return data
  • 尝试从指定路径加载 CSV 文件
  • 如果文件不存在,会生成模拟数据:
    • 使用正态分布生成房价、面积数据
    • 使用均匀分布生成房龄数据
    • 通过公式price = base_price + 50*area - 100*age确保房价与面积正相关,与房龄负相关
    • 设置房价下限为 5000 万元

数据house_prices.csv

area,price,age,bedrooms
120,15000,10,3
140,18000,5,4
90,12000,15,2
160,20000,8,3
100,13000,12,2
92,12000,15,2
162,20000,8,3
102,13000,12,2
91,12000,15,2
161,20000,8,3
101,12000,12,2
121,13000,10,3
142,16000,5,4
122,13000,10,3
142,15000,5,4
123,17000,10,3
144,17000,5,4
124,17000,10,3
144,17000,5,4
125,18000,10,3
145,18000,5,4

1.4、房价分布可视化函数 plot_price_distribution()

def plot_price_distribution(data, price_col='price'):"""绘制房价分布直方图"""plt.figure(figsize=(10, 6))# 绘制直方图和核密度估计sns.histplot(data[price_col], kde=True, bins=30, color='skyblue')# 添加均值和中位数线mean_val = data[price_col].mean()median_val = data[price_col].median()plt.axvline(mean_val, color='red', linestyle='dashed', linewidth=2, label=f'均值: {mean_val:.2f}')plt.axvline(median_val, color='green', linestyle='dashed', linewidth=2, label=f'中位数: {median_val:.2f}')# 添加正态分布拟合曲线mu, sigma = stats.norm.fit(data[price_col])x = np.linspace(data[price_col].min(), data[price_col].max(), 100)plt.plot(x, stats.norm.pdf(x, mu, sigma) * len(data) * (x.max() - x.min()) / 100,'r--', linewidth=2, label=f'正态分布拟合: μ={mu:.2f}, σ={sigma:.2f}')plt.title('房价分布直方图')plt.xlabel('房价 (万元)')plt.ylabel('频数')plt.legend()plt.grid(axis='y', alpha=0.5)plt.tight_layout()# 保存图像if not os.path.exists('plots'):os.makedirs('plots')plt.savefig('plots/price_distribution.png', dpi=300)plt.show()# 打印统计信息print("\n房价统计信息:")print(data[price_col].describe())# 检验正态性stat, p = stats.normaltest(data[price_col])print(f"\n正态性检验 (p值): {p:.4f}")if p < 0.05:print("房价分布显著偏离正态分布")else:print("房价分布近似正态分布")
  • 创建 10x6 英寸的图表
  • 使用 seaborn 绘制直方图和核密度估计曲线
  • 添加均值 (红色虚线) 和中位数 (绿色虚线) 参考线
  • 拟合正态分布曲线并绘制 (红色虚线)
  • 设置图表标题、轴标签,添加图例和网格线
  • 将图表保存到 plots 文件夹,并显示图表
  • 打印房价的描述性统计信息 (计数、均值、标准差等)
  • 使用stats.normaltest进行正态性检验并输出结果

1.5、主函数 main()

def main():"""主函数:执行数据加载和价格分布分析"""file_path = '../../data/house_prices.csv'  # 替换为实际文件路径# 1. 加载数据data = load_data(file_path)# 2. 绘制房价分布直方图plot_price_distribution(data)print("\n数据分析完成!图表已保存到 'plots' 文件夹")
  • 设置数据文件路径
  • 调用load_data()加载数据
  • 调用plot_price_distribution()分析并可视化房价分布
  • 打印分析完成信息

1.6、程序入口

if __name__ == "__main__":
main()

  • 确保程序作为脚本直接运行时才执行main()函数
  • 如果作为模块导入,则不会执行

代码优化建议

  1. 添加更多错误处理,如处理空数据的情况
  2. 可以将图表保存路径作为参数传入
  3. 正态分布曲线的高度计算可以更精确
  4. 可以添加更多的房价分析维度,如不同房龄、面积段的价格分布

二、代码和执行结果

2.1、代码

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats
import os# 设置 Windows 系统的中文字体
plt.rcParams["font.family"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题def load_data(file_path):"""加载房价数据"""try:# 尝试读取CSV文件data = pd.read_csv(file_path)print(f"数据加载成功,共{data.shape[0]}条记录,{data.shape[1]}个特征")print(f"数据特征: {', '.join(data.columns.tolist())}")return dataexcept FileNotFoundError:print(f"错误: 文件 '{file_path}' 不存在")# 创建示例数据用于演示print("创建示例数据用于演示...")np.random.seed(42)size = 500data = pd.DataFrame({'price': np.random.normal(15000, 3000, size),  # 房价,单位:万元'area': np.random.normal(100, 20, size),  # 面积,单位:平方米'age': np.random.randint(1, 30, size),  # 房龄,单位:年})# 确保房价与面积正相关,与房龄负相关data['price'] = data['price'] + 50 * data['area'] - 100 * data['age']data['price'] = data['price'].clip(lower=5000)  # 设置价格下限return datadef plot_price_distribution(data, price_col='price'):"""绘制房价分布直方图"""plt.figure(figsize=(10, 6))# 绘制直方图和核密度估计sns.histplot(data[price_col], kde=True, bins=30, color='skyblue')# 添加均值和中位数线mean_val = data[price_col].mean()median_val = data[price_col].median()plt.axvline(mean_val, color='red', linestyle='dashed', linewidth=2, label=f'均值: {mean_val:.2f}')plt.axvline(median_val, color='green', linestyle='dashed', linewidth=2, label=f'中位数: {median_val:.2f}')# 添加正态分布拟合曲线mu, sigma = stats.norm.fit(data[price_col])x = np.linspace(data[price_col].min(), data[price_col].max(), 100)plt.plot(x, stats.norm.pdf(x, mu, sigma) * len(data) * (x.max() - x.min()) / 100,'r--', linewidth=2, label=f'正态分布拟合: μ={mu:.2f}, σ={sigma:.2f}')plt.title('房价分布直方图')plt.xlabel('房价 (万元)')plt.ylabel('频数')plt.legend()plt.grid(axis='y', alpha=0.5)plt.tight_layout()# 保存图像if not os.path.exists('plots'):os.makedirs('plots')plt.savefig('plots/price_distribution.png', dpi=300)plt.show()# 打印统计信息print("\n房价统计信息:")print(data[price_col].describe())# 检验正态性stat, p = stats.normaltest(data[price_col])print(f"\n正态性检验 (p值): {p:.4f}")if p < 0.05:print("房价分布显著偏离正态分布")else:print("房价分布近似正态分布")def main():"""主函数:执行数据加载和价格分布分析"""file_path = '../../data/house_prices.csv'  # 替换为实际文件路径# 1. 加载数据data = load_data(file_path)# 2. 绘制房价分布直方图plot_price_distribution(data)print("\n数据分析完成!图表已保存到 'plots' 文件夹")if __name__ == "__main__":main()

2.2、执行结果

数据加载成功,共21条记录,4个特征
数据特征: area, price, age, bedrooms

房价统计信息:
count       21.000000
mean     15619.047619
std       2854.403449
min      12000.000000
25%      13000.000000
50%      16000.000000
75%      18000.000000
max      20000.000000
Name: price, dtype: float64

正态性检验 (p值): 0.0725
房价分布近似正态分布

数据分析完成!图表已保存到 'plots' 文件夹

三、1.4中的部分详解

1.4.1、正态分布拟合曲线绘制代码详解

mu, sigma = stats.norm.fit(data[price_col])
x = np.linspace(data[price_col].min(), data[price_col].max(), 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma) * len(data) * (x.max() - x.min()) / 100,
'r--', linewidth=2, label=f'正态分布拟合: μ={mu:.2f}, σ={sigma:.2f}')

1. 计算正态分布参数

mu, sigma = stats.norm.fit(data[price_col])

  • stats.norm.fit() 是 SciPy 库中用于拟合正态分布的函数
  • 它使用最大似然估计方法,根据输入数据计算最匹配的正态分布参数
  • 返回两个值:
    • mu:正态分布的均值(位置参数)
    • sigma:正态分布的标准差(尺度参数)
2. 生成曲线绘制的 x 坐标

x = np.linspace(data[price_col].min(), data[price_col].max(), 100)

  • np.linspace() 在房价数据的最小值和最大值之间生成 100 个均匀分布的点
  • 这 100 个点将作为曲线的 x 坐标,确保曲线覆盖整个数据范围
  • 例如,如果房价最小值是 5000,最大值是 25000,则会生成从 5000 到 25000 的 100 个点
3. 计算正态分布曲线的 y 坐标(核心难点)

stats.norm.pdf(x, mu, sigma) * len(data) * (x.max() - x.min()) / 100

这部分代码可以分解为三个关键部分:

3.1 计算理论概率密度值

stats.norm.pdf(x, mu, sigma)

  • stats.norm.pdf() 计算正态分布的概率密度函数 (Probability Density Function, PDF)
  • 输入参数:
    • x:前面生成的 100 个房价坐标点
    • mu 和 sigma:前面拟合得到的正态分布参数
  • 输出:每个 x 点对应的正态分布概率密度值
3.2 缩放因子 - 样本量调整

* len(data)

  • 乘以样本数量(数据行数)
  • 这一步将概率密度转换为理论频数
  • 例如,如果某个房价区间的理论概率是 0.05,样本量是 500,则理论频数是 0.05 * 500 = 25
3.3 缩放因子 - 区间宽度调整

* (x.max() - x.min()) / 100

  • (x.max() - x.min()) / 100 计算每个区间的宽度
  • 这一步调整曲线高度以匹配直方图的区间宽度
  • 例如,如果房价范围是 20000(25000-5000),分成 100 个区间,则每个区间宽度是 200
4. 绘制正态分布曲线

plt.plot(x, y, 'r--', linewidth=2, label=f'正态分布拟合: μ={mu:.2f}, σ={sigma:.2f}')

  • 使用 matplotlib 的 plot 函数绘制曲线
  • 参数说明:
    • x:横坐标(房价值)
    • y:纵坐标(调整后的理论频数)
    • 'r--':红色虚线
    • linewidth=2:线宽 2
    • label:图例标签,显示拟合的正态分布参数(保留两位小数)

为什么需要这些缩放因子?

正态分布的概率密度函数 (PDF) 返回的是概率密度值,范围通常很小(例如 0-0.0001),直接绘制会与直方图的高度不匹配。通过乘以样本量和区间宽度,可以将理论概率密度转换为与直方图可比的理论频数,使曲线与直方图在同一尺度上显示,便于直观比较数据分布与正态分布的拟合程度。

示例说明

假设:

  • 房价数据范围:5000-25000 万元
  • 样本量:500 条
  • 拟合的正态分布参数:μ=15000, σ=3000
  • 某点 x=15000 处的概率密度值:stats.norm.pdf (15000, 15000, 3000) ≈ 0.000133

经过缩放计算:

0.000133 * 500 * (25000-5000)/100 ≈ 0.000133 * 500 * 200 ≈ 13.3

这意味着在 x=15000 处,理论上该区间的频数约为 13.3,这个值与直方图在该区间的高度可比。

常见问题与优化

  1. 如果直方图的 bins 数量不是 100,需要相应调整缩放因子中的分母
  2. 对于偏态分布,正态拟合可能不佳,可以考虑使用其他分布(如对数正态、伽马分布等)
  3. 可以添加判断逻辑,根据 bins 数量自动计算缩放因子,提高代码通用性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89134.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89134.shtml
英文地址,请注明出处:http://en.pswp.cn/web/89134.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端三剑客之CSS

1. CSS 简介1) CSS 简述CSS&#xff0c;即层叠样式表&#xff08;英文全称&#xff1a;Cascading Style Sheets&#xff09;&#xff0c;是一种专门用于修饰 HTML 文档呈现样式的计算机语言。它的功能不仅限于静态美化网页&#xff0c;还能与各类脚本语言配合&#xff0c;实现对…

力扣25.7.11每日一题——无需开会的工作日

Description 这题类似合并区间&#xff0c;题意你们都能看懂吧…… Solution 这道题就需要用到合并区间的方法。 答案等于 daysdaysdays 减「有会议安排的天数」。 对左端点进行排序&#xff0c;计算有会议安排的天数&#xff0c;累加每个区间的长度&#xff0c;即为有会议…

每日一SQL 【销售分析 III】

文章目录问题案例执行顺序使用分组解决问题 案例 执行顺序 SQL 语句的执行顺序&#xff08;核心步骤&#xff09; 同一层级的select查询内部, 别名在整个 SELECT 计算完成前不生效 使用分组解决 select distinct s.product_id, Product.product_name from Sales sleft join …

轻轻松松带你进行-负载均衡LVS实战

8. LVS部署命令介绍 8.1 LVS软件相关信息 1.程序包&#xff1a;ipvsadm 2.Unit File: ipvsadm.service 3.主程序&#xff1a;/usr/sbin/ipvsadm 4.规则保存工具&#xff1a;/usr/sbin/ipvsadm-save 5.规则重载工具&#xff1a;/usr/sbin/ipvsadm-restore 6.配置文件&#xff1a…

C#.NET 集合框架详解

简介 C# 集合框架是处理数据集合的核心组件&#xff0c;位于 System.Collections 和 System.Collections.Generic 命名空间。它提供了多种数据结构来高效存储和操作数据。 集合框架概览 System.Collections (非泛型老版) └─ System.Collections.Generic (泛…

网络劫持对用户隐私安全的影响:一场无形的数据窃取危机

在互联网时代&#xff0c;网络劫持如同一把“隐形镰刀”&#xff0c;悄然威胁着用户的隐私安全。当我们在浏览网页、使用社交媒体或进行在线交易时&#xff0c;看似正常的网络连接背后&#xff0c;可能正暗藏着数据被窃取的风险。网络劫持通过多种技术手段干预用户与服务器的正…

使用 Helm 下载 Milvus 安装包(Chart)指南

目录 &#x1f4e6; 使用 Helm 下载 Milvus 安装包&#xff08;Chart&#xff09;指南 &#x1f6e0; 环境准备 &#x1f680; 第一步&#xff1a;添加 Milvus Helm 仓库 &#x1f50d; 第二步&#xff1a;查看可用版本 &#x1f4e5; 第三步&#xff1a;下载指定版本的 C…

EXTI 外部中断

目录 STM32中断 NVIC 中断控制器 NVIC优先级分组 EXTI 外部中断 AFIO 复用IO口 外部中断/事件控制器&#xff08;EXTI&#xff09;框图 STM32中断 在STM32微控制器中&#xff0c;共有68个可屏蔽中断通道&#xff0c;涵盖了多个外设&#xff0c;如外部中断&#xff08;EXT…

WebApplicationType.REACTIVE 的webSocket

通用请求体类 Data ApiModel("websocket请求消息") public class WebSocketRequest<T> implements Serializable {private static final long serialVersionUID 1L;/*** 参考&#xff1a;com.mcmcnet.gacne.basic.service.common.pojo.enumeration.screen.AiB…

降本增效!自动化UI测试平台TestComplete并行测试亮点

在跨平台自动化测试中&#xff0c;企业常面临设备投入高、串行测试耗时长、测试覆盖率难以兼顾的困境。自动化UI测试平台TestComplete的并行测试引擎提供了有效的解决方案&#xff1a;通过云端海量设备池与CI/CD深度集成&#xff0c;实现多平台、多浏览器并行测试&#xff0c;显…

云、实时、时序数据库混合应用:医疗数据管理的革新与展望(上)

云、实时、时序数据库混合应用:医疗数据管理的革新与展望 1、引言 1.1 研究背景与意义 在信息技术飞速发展的当下,医疗行业正经历着深刻的数字化转型。这一转型不仅是技术层面的革新,更是关乎医疗体系未来发展方向的深刻变革。从医疗服务的提供方式,到医疗管理的模式,再…

代码随想录算法训练营十六天|二叉树part06

LeetCode 530 二叉搜索树的最小绝对差 题目链接&#xff1a;530. 二叉搜索树的最小绝对差 - 力扣&#xff08;LeetCode&#xff09; 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差…

自增主键为什么不是连续的?

前言 如果一个线程回滚&#xff0c;例如唯一键冲突的情况回滚时&#xff0c;回滚了sql语句&#xff0c;但是并没有把自增的值也-1。那么就会导致下一条插入的数据自增id出现了跳跃。 自增主键为什么不是连续的&#xff1f;前言执行时机为什么自增主键不是连续的为什么不回滚自…

OpenCV图像基本操作:读取、显示与保存

在图像处理项目中&#xff0c;图像的 读取&#xff08;imread&#xff09;、显示&#xff08;imshow&#xff09; 和 保存&#xff08;imwrite&#xff09; 是最基础也是最常用的三个操作。本文将详细介绍这三个函数的功能、用法和注意事项&#xff0c;并提供一个完整示例供读者…

.NET控制台应用程序中防止程序立即退出

在VB.NET控制台应用程序中防止程序立即退出&#xff0c;主要有以下几种常用方法&#xff0c;根据需求选择适合的方案&#xff1a; 方法1&#xff1a;等待用户输入&#xff08;推荐&#xff09; Module Module1Sub Main()Console.WriteLine("程序开始运行...") 这里是…

Vue3 + Three.js 极速入门:打造你的第一个3D可视化项目

文章目录前言一、环境准备1.1 创建Vue3项目1.2 安装Three.js二、Three.js核心概念速览三、实战&#xff1a;创建旋转立方体3.1 组件化初始化四、核心代码解析4.1 Vue3响应式整合技巧4.2 性能优化要点五、进阶功能扩展5.1 数据驱动控制5.2 加载3D模型六、常见问题解决七、资源推…

【设计模式】享元模式(轻量级模式) 单纯享元模式和复合享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;详解一、享元模式简介 享元模式&#xff08;Flyweight Pattern&#xff09; 是一种 结构型设计模式&#xff08;对象结构型模式&#xff09;&#xff0c;它通过共享技术实现相同或相似对象的重用&#xff0c;以减少内存占用和…

驱动开发_2.字符设备驱动

目录1. 什么是字符设备2. 设备号2.1 设备号概念2.2 通过设备号dev分别获取主、次设备号的宏函数2.3 主设备号的申请静态申请动态分配2.4 注销设备号3. 字符设备3.1 注册字符设备3.2 注销字符设备3.3 应用程序和驱动程序的关系3.4 file_opertaions结构体3.5 class_create3.6 创建…

直播推流技术底层逻辑详解与私有化实现方案-以rmtp rtc hls为例-优雅草卓伊凡

直播推流技术底层逻辑详解与私有化实现方案-以rmtp rtc hls为例-优雅草卓伊凡由于我们的甲方客户要开始为我们项目产品上加入私有化的直播&#xff0c;这块不得不又捡起来曾经我们做直播推流的事情了&#xff0c;其实私有化直播一直并不是一件容易的事情&#xff0c;现在大部分…

一文读懂现代卷积神经网络—深度卷积神经网络(AlexNet)

目录 深度卷积神经网络&#xff08;AlexNet&#xff09;是什么&#xff1f; 一、AlexNet 的核心创新 1. 深度架构 2. ReLU 激活函数 3. 数据增强 4. Dropout 正则化 5. GPU 并行计算 6. 局部响应归一化&#xff08;LRN&#xff09; 二、AlexNet 的网络结构 三、AlexN…