初学者也能懂!用Python做房屋销售数据分析,从0到1上手实战(附源码和数据)

发布于:2025-09-04 ⋅ 阅读:(25) ⋅ 点赞:(0)

初学者也能懂!用Python做房屋销售数据分析,从0到1上手实战

大家好!今天带大家做一个超实用的数据分析小demo——房屋销售数据分析。不管你是刚学Python的新手,还是想入门数据分析的同学,跟着这篇文章走,你不仅能看懂代码,还能亲手跑出属于自己的分析结果,甚至能从数据里挖出关于房价的小秘密~

一、先搞懂:我们要做什么?用什么做?

1. 目标

我们有一份房屋销售的CSV数据(比如包含房屋面积、卧室数、价格、销售日期等信息),要通过Python完成:

  • 加载数据并看看数据长啥样(有没有问题)
  • 清理数据(补漏洞、加新信息)
  • 画图表看规律(比如房价分布、哪个区房子贵)
  • 分析影响房价的因素(面积?卧室数?)
  • 看销售趋势(哪个月卖得多?)

2. 用到的“工具库”

就像做饭需要锅碗瓢盆,数据分析也需要专门的Python库,我们这次用4个核心库:

库名 作用 通俗理解
pandas 数据处理(读数据、算统计) 数据的“记事本+计算器”
numpy 数值计算(帮我们算模型) 更强大的“计算器”
matplotlib 画图表(直方图、散点图) 数据的“画图板”
seaborn 美化图表(比如热力图) 图表的“化妆师”

二、第一步:环境准备(新手必看)

在写代码前,得先把“工具”装好。打开你的Python编辑器(比如PyCharm、VS Code,没有的同学可以百度下载一下就行),有python环境后,先执行下面的命令安装需要的库:

pip install pandas numpy matplotlib seaborn

安装完成后,我们先写一段“准备代码”,避免后续出小问题(比如图表中文乱码):

# 导入所有需要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import os

# 关键!设置中文字体(不然图表里的中文会变成乱码方框)
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用“黑体”显示中文
plt.rcParams['axes.unicode_minus'] = False    # 解决负号显示问题

三、第二步:加载数据,先“摸透”数据长啥样

拿到数据第一步,不是直接分析,而是先看看数据“健康”吗?有多少行多少列?有没有缺数据?这一步我们写个load_and_explore_data()函数来搞定。

1. 代码拆解:加载数据并检查

def load_and_explore_data():
    print("=== 房屋销售数据分析案例 ===\n")
    
    # 1. 先确认数据文件在不在
    csv_file = 'house_sales_data.csv'  # 你的数据文件名
    if not os.path.exists(csv_file):
        print(f"错误: 找不到数据文件 {csv_file}")
        print("请准备这样的CSV文件,必须包含这些列:")
        print("house_id(房屋ID), area(面积), bedrooms(卧室数), bathrooms(卫生间数),")
        print("location(区域), age(房龄), price(价格), sale_date(销售日期), sale_status(销售状态)")
        return None  # 文件不在就退出,避免报错
    
    # 2. 读取CSV数据(pandas的核心功能!)
    try:
        df = pd.read_csv(csv_file)  # df是“DataFrame”,像Excel表格一样的结构
        
        # 把“销售日期”转成日期格式(方便后续按日期分析)
        if 'sale_date' in df.columns:
            df['sale_date'] = pd.to_datetime(df['sale_date'])
        
        # 3. 打印数据概览,让我们“眼见为实”
        print("1. 数据概览:")
        print(f"数据集形状: {df.shape}")  # (行数, 列数),比如(1000,9)就是1000条数据,9个字段
        print("\n前5行数据(看看长啥样):")
        print(df.head())  # 显示前5行,避免数据太多看不过来
        
        print("\n2. 数据基本信息(有没有缺失值、数据类型):")
        print(df.info())  # 重点看“Non-Null Count”,如果比总行数少,就是有缺失值
        
        print("\n3. 数值型数据统计(平均值、最大值这些):")
        print(df.describe())  # 只对数字列生效,比如面积的平均值、房价的最大值
        
        print("\n4. 分类数据统计(比如哪个区房子多):")
        if 'location' in df.columns:
            print("各区房屋数量:")
            print(df['location'].value_counts())  # 统计每个区域有多少套房子
        if 'sale_status' in df.columns:
            print("\n销售状态统计(比如已售/待售):")
            print(df['sale_status'].value_counts())
        
        return df  # 返回清洗好的“表格”,给后续步骤用
    
    except Exception as e:
        print(f"读文件出错了: {e}")  # 万一格式错了,告诉我们哪里错了
        return None

2. 新手必问:这步能得到什么?

举个例子,如果你的数据有1000条房屋记录,运行后会看到:

  • 数据集形状:(1000, 9)(1000行数据,9列信息)
  • 前5行能看到具体数据,比如某套房子面积120㎡,3个卧室,价格200万
  • df.info()能发现:比如“age(房龄)”列有10个缺失值(需要后续处理)
  • df.describe()能看到:房价平均180万,最高500万,最低80万
  • 从区域统计能看到:“城东”区房子最多(300套),“城西”最少(150套)

四、第三步:数据清洗——“修bug”的关键一步

拿到的数据很少是“完美”的,比如有缺失值、重复值,或者需要加一些新信息(比如“每平米单价”)。这一步我们用clean_data()函数搞定。

1. 代码拆解:清洗数据

def clean_data(df):
    print("\n=== 数据清洗 ===")
    
    # 1. 检查缺失值(数据里的“空格子”)
    print("缺失值检查(每列有多少空值):")
    print(df.isnull().sum())  # 比如age列有10个空值,这里就会显示10
    
    # 2. 检查重复值(完全一样的行,可能是录入错误)
    print(f"\n重复值数量: {df.duplicated().sum()}")  # 比如有5个重复行
    
    # 3. 新增有用的特征(让数据更有分析价值)
    # 新增“每平米单价”:总价/面积(买房时最关心的指标之一)
    if 'price' in df.columns and 'area' in df.columns:
        df['price_per_sqm'] = df['price'] / df['area']  # 自动新增一列
    
    # 新增“月份”“季度”:方便按时间分析(比如3月卖了多少套)
    if 'sale_date' in df.columns:
        df['month'] = df['sale_date'].dt.month  # 提取月份(1-12)
        df['quarter'] = df['sale_date'].dt.quarter  # 提取季度(1-4)
    
    # (新手拓展:如果有缺失值,怎么处理?)
    # 比如用“房龄的平均值”填充age列的空值:df['age'].fillna(df['age'].mean(), inplace=True)
    # 比如删除重复值:df.drop_duplicates(inplace=True)
    
    print("\n新增特征后的数据(看最后3列):")
    print(df.head())  # 会看到多了price_per_sqm、month、quarter三列
    
    return df

2. 为什么要做数据清洗?

  • 缺失值会导致后续画图或建模报错(比如算平均房价时,空值会让结果不准)
  • 重复值会让数据“虚高”(比如1条数据重复5次,会误以为有5套房子)
  • 新增特征能帮我们挖掘更多信息:比如“每平米单价”能直接对比不同区域的房价高低,比总价更直观

五、第四步:探索性数据分析——画图看规律!

数据分析的核心是“可视化”——用图表代替枯燥的数字,一眼看出规律。这一步exploratory_analysis()函数会生成2张综合图表,包含4个关键分析。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. 代码拆解:画图表找规律

def exploratory_analysis(df):
    print("\n=== 探索性数据分析 ===")
    
    # 1. 画第一张图:包含4个子图(价格分布、面积分布、各区均价、面积vs价格)
    plt.figure(figsize=(15, 10))  # 设置图的大小(宽15,高10)
    
    # 子图1:房屋价格分布(直方图)
    plt.subplot(2, 2, 1)  # 2行2列的第1个位置
    plt.hist(df['price'], bins=20, alpha=0.7, color='skyblue', edgecolor='black')
    plt.title('房屋价格分布')  # 标题
    plt.xlabel('价格(元)')     # X轴标签
    plt.ylabel('频数')        # Y轴标签(有多少套房子在这个价格区间)
    
    # 子图2:房屋面积分布(直方图)
    plt.subplot(2, 2, 2)  # 2行2列的第2个位置
    plt.hist(df['area'], bins=15, alpha=0.7, color='lightgreen', edgecolor='black')
    plt.title('房屋面积分布')
    plt.xlabel('面积(平方米)')
    plt.ylabel('频数')
    
    # 子图3:各区平均价格(柱状图)
    plt.subplot(2, 2, 3)  # 2行2列的第3个位置
    avg_price_by_location = df.groupby('location')['price'].mean().sort_values()  # 按区域算均价并排序
    avg_price_by_location.plot(kind='bar', color='orange', alpha=0.7)
    plt.title('各区平均房屋价格')
    plt.xlabel('区域')
    plt.ylabel('平均价格(元)')
    plt.xticks(rotation=45)  # 区域名旋转45度,避免重叠
    
    # 子图4:面积与价格的关系(散点图)
    plt.subplot(2, 2, 4)  # 2行2列的第4个位置
    plt.scatter(df['area'], df['price'], alpha=0.6, color='purple')  # 每个点代表一套房子
    plt.title('房屋面积与价格关系')
    plt.xlabel('面积(平方米)')
    plt.ylabel('价格(元)')
    
    plt.tight_layout()  # 自动调整子图位置,避免重叠
    plt.savefig('house_sales_analysis1.png', dpi=300, bbox_inches='tight')  # 保存图片(高清)
    plt.show()  # 显示图片
    
    # 2. 画第二张图:卧室数量影响、月度销售情况
    plt.figure(figsize=(12, 5))
    
    # 子图1:卧室数量对均价的影响(柱状图)
    plt.subplot(1, 2, 1)  # 1行2列的第1个位置
    avg_price_by_bedrooms = df.groupby('bedrooms')['price'].mean()  # 按卧室数算均价
    avg_price_by_bedrooms.plot(kind='bar', color='lightcoral', alpha=0.7)
    plt.title('卧室数量对平均价格的影响')
    plt.xlabel('卧室数量')
    plt.ylabel('平均价格(元)')
    plt.xticks(rotation=0)  # 卧室数少,不用旋转
    
    # 子图2:每月销售数量(折线图)
    plt.subplot(1, 2, 2)  # 1行2列的第2个位置
    sales_by_month = df.groupby('month').size()  # 按月份统计销售套数
    sales_by_month.plot(kind='line', marker='o', color='blue', linewidth=2)  # 折线图+圆点标记
    plt.title('每月房屋销售数量')
    plt.xlabel('月份')
    plt.ylabel('销售数量')
    plt.xticks(range(1, 13))  # X轴显示1-12月
    
    plt.tight_layout()
    plt.savefig('house_sales_analysis2.png', dpi=300, bbox_inches='tight')
    plt.show()

2. 这张图能告诉我们什么?(新手必看)

举个实际分析结果的例子:

  • 价格分布:大部分房子价格在150-250万之间(直方图的“山峰”在这个区间),只有少数豪宅超过400万
  • 面积分布:面积集中在90-130㎡(刚需户型为主),180㎡以上的大户型很少
  • 各区均价:“城南”区均价最高(2.5万/㎡),“城北”最低(1.8万/㎡)(柱状图从低到高排,一眼看清)
  • 面积与价格:散点图呈“斜向上”的趋势——面积越大,价格越高(正相关)
  • 卧室数量影响:4卧室房子均价(280万)> 3卧室(200万)> 2卧室(150万)(卧室越多越贵)
  • 月度销售:3月和9月销售高峰(可能是金三银九),1月销售最少(春节前后)

六、第五步:深入分析——找影响房价的关键因素

光看表面规律还不够,我们还要用“数据说话”:哪些因素对房价影响最大?用简单的机器学习模型(线性回归)来分析。

1. 代码拆解:深入分析(含机器学习入门)

def advanced_analysis(df):
    print("\n=== 深入分析 ===")
    
    # 1. 计算相关系数(看变量之间的“关系紧密程度”)
    numeric_cols = ['area', 'bedrooms', 'bathrooms', 'age', 'price', 'price_per_sqm']  # 数值型变量
    correlation_matrix = df[numeric_cols].corr()  # 生成相关系数矩阵
    
    print("数值变量相关系数矩阵(越接近1,关系越紧密):")
    print(correlation_matrix.round(2))  # 保留2位小数,更易读
    
    # 画相关系数热力图(更直观)
    plt.figure(figsize=(10, 8))
    sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0,
                square=True, fmt='.2f', cbar_kws={'shrink': .8})
    plt.title('变量间相关系数热力图')
    plt.tight_layout()
    plt.savefig('correlation_heatmap.png', dpi=300, bbox_inches='tight')
    plt.show()
    
    # 2. 各区每平米均价分析(比总价更公平)
    print("\n各区每平米均价(含标准差和数量):")
    price_per_sqm_by_location = df.groupby('location')['price_per_sqm'].agg(['mean', 'std', 'count'])
    # mean=均价,std=标准差(价格波动大小),count=房子数量
    print(price_per_sqm_by_location.round(2))
    
    # 3. 简单房价预测模型(线性回归)
    from sklearn.linear_model import LinearRegression  # 导入线性回归模型
    from sklearn.model_selection import train_test_split  # 拆分训练/测试数据
    from sklearn.metrics import mean_squared_error, r2_score  # 模型评估指标
    
    # 选择“特征”(用来预测的因素)和“目标”(要预测的结果)
    X = df[['area', 'bedrooms', 'bathrooms', 'age']]  # 特征:面积、卧室数、卫生间数、房龄
    y = df['price']  # 目标:房价
    
    # 拆分数据:80%用来训练模型,20%用来测试模型准不准
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
    # 训练模型(让电脑从数据里学规律)
    model = LinearRegression()
    model.fit(X_train, y_train)
    
    # 用模型预测测试集的房价
    y_pred = model.predict(X_test)
    
    # 评估模型(看预测得准不准)
    print(f"\n模型评估结果:")
    print(f"R²分数: {r2_score(y_test, y_pred):.3f}")  # 越接近1,预测越准(0.7以上算不错)
    print(f"均方根误差(RMSE): {np.sqrt(mean_squared_error(y_test, y_pred)):.2f}")  # 平均误差(越小越好)
    
    # 分析“特征重要性”(哪个因素对房价影响最大)
    feature_importance = pd.DataFrame({
        'feature': X.columns,  # 特征名(面积、卧室数等)
        'coefficient': model.coef_,  # 系数(正负代表影响方向,绝对值代表影响大小)
        'abs_importance': abs(model.coef_)  # 系数绝对值(方便排序)
    }).sort_values('abs_importance', ascending=False)  # 按重要性从大到小排
    
    print("\n特征重要性(哪个因素对房价影响最大):")
    print(feature_importance)

2. 新手能看懂的关键结论

  • 相关系数:比如“area(面积)”和“price(房价)”的相关系数是0.85(接近1),说明面积对房价影响极大;“age(房龄)”和“price”相关系数是-0.3(负的),说明房龄越大,房价越低(符合常识)
  • 热力图:红色代表正相关(越红越相关),蓝色代表负相关(越蓝越负相关),一眼看出面积和房价最红(关系最铁)
  • 每平米均价:“城南”不仅总价高,每平米均价也高(2.5万/㎡),而且标准差小(价格稳定),说明城南房价坚挺
  • 模型结果:比如R²=0.75,说明用面积、卧室数等4个特征,能解释75%的房价变化(算不错的模型);RMSE=20万,说明预测房价时,平均误差约20万
  • 特征重要性:面积的系数最大(比如10000),说明面积每增加1㎡,房价平均涨1万元;房龄系数是-5000,说明房龄每增加1年,房价平均降5000元

七、第六步:销售趋势分析——看时间规律

最后,我们分析销售的时间趋势,比如每周卖多少套,哪个季度房价最高。

1. 代码拆解:销售趋势

def sales_trend_analysis(df):
    print("\n=== 销售趋势分析 ===")
    
    # 新增“周数”列(按年份的周数,1-52周)
    df['week'] = df['sale_date'].dt.isocalendar().week
    
    # 画趋势图(2个子图)
    plt.figure(figsize=(12, 5))
    
    # 子图1:每周销售趋势(折线图)
    plt.subplot(1, 2, 1)
    weekly_sales = df.groupby('week').size()  # 按周统计销售套数
    weekly_sales.plot(kind='line', marker='o', color='green', linewidth=2)
    plt.title('每周房屋销售趋势')
    plt.xlabel('周数')
    plt.ylabel('销售数量')
    plt.grid(True, alpha=0.3)  # 加网格,方便看数值
    
    # 子图2:各季度平均房价(柱状图)
    plt.subplot(1, 2, 2)
    quarterly_avg_price = df.groupby('quarter')['price'].mean()  # 按季度算均价
    quarterly_avg_price.plot(kind='bar', color='lightblue', alpha=0.7)
    plt.title('各季度平均房屋价格')
    plt.xlabel('季度')
    plt.ylabel('平均价格(元)')
    plt.xticks(rotation=0)
    
    plt.tight_layout()
    plt.savefig('sales_trend_analysis.png', dpi=300, bbox_inches='tight')
    plt.show()

2. 趋势结论

比如你可能会发现:

  • 每周销售:第10周(3月)和第36周(9月)是销售高峰,第52周(12月底)是低谷
  • 季度均价:第2季度(4-6月)和第3季度(7-9月)均价最高,第1季度(1-3月)最低

八、最后一步:把所有功能串起来,一键运行!

前面我们写了很多“小功能”,现在用main()函数把它们串起来,一键完成整个分析流程:

def main():
    try:
        # 1. 加载和探索数据
        df = load_and_explore_data()
        if df is None:  # 数据加载失败就退出
            return
        
        # 2. 数据清洗
        df_clean = clean_data(df)
        
        # 3. 探索性分析
        exploratory_analysis(df_clean)
        
        # 4. 深入分析
        advanced_analysis(df_clean)
        
        # 5. 销售趋势分析
        sales_trend_analysis(df_clean)
        
        # 分析完成!告诉用户生成了哪些文件
        print("\n=== 分析完成 ===")
        print("已生成4张分析图表:")
        print("- house_sales_analysis1.png: 价格/面积分布+各区均价+面积vs价格")
        print("- house_sales_analysis2.png: 卧室数量影响+月度销售")
        print("- correlation_heatmap.png: 变量相关系数热力图")
        print("- sales_trend_analysis.png: 每周销售+季度均价")
        
        # 保存清洗后的数据(方便后续复用)
        df_clean.to_csv('cleaned_house_sales_data.csv', index=False, encoding='utf-8-sig')
        print("\n清洗后的数据已保存到: cleaned_house_sales_data.csv")
        
    except Exception as e:
        print(f"分析过程中出错: {e}")

# 只有运行这个文件时,才执行main()函数
if __name__ == "__main__":
    main()

九、源代码获取

代码复制即可运行:

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

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

# 数据加载和初步探索
def load_and_explore_data():
    print("=== 房屋销售数据分析案例 ===\n")
    
    # 从CSV文件读取数据
    csv_file = 'house_sales_data.csv'
    
    if not os.path.exists(csv_file):
        print(f"错误: 找不到数据文件 {csv_file}")
        print("请确保house_sales_data.csv文件存在于当前目录")
        print("文件应包含以下列: house_id, area, bedrooms, bathrooms, location, age, price, sale_date, sale_status")
        return None
    
    try:
        # 读取CSV文件
        df = pd.read_csv(csv_file)
        
        # 转换日期列
        if 'sale_date' in df.columns:
            df['sale_date'] = pd.to_datetime(df['sale_date'])
        
        print("1. 数据概览:")
        print(f"数据集形状: {df.shape}")
        print("\n前5行数据:")
        print(df.head())
        
        print("\n2. 数据基本信息:")
        print(df.info())
        
        print("\n3. 数值型数据描述性统计:")
        print(df.describe())
        
        print("\n4. 分类变量统计:")
        if 'location' in df.columns:
            print("各区房屋数量:")
            print(df['location'].value_counts())
        
        if 'sale_status' in df.columns:
            print("\n销售状态统计:")
            print(df['sale_status'].value_counts())
        
        return df
        
    except Exception as e:
        print(f"读取文件时出错: {e}")
        return None

# 数据清洗
def clean_data(df):
    print("\n=== 数据清洗 ===")
    
    # 检查缺失值
    print("缺失值检查:")
    print(df.isnull().sum())
    
    # 检查重复值
    print(f"\n重复值数量: {df.duplicated().sum()}")
    
    # 添加新特征
    if 'price' in df.columns and 'area' in df.columns:
        df['price_per_sqm'] = df['price'] / df['area']
    
    if 'sale_date' in df.columns:
        df['month'] = df['sale_date'].dt.month
        df['quarter'] = df['sale_date'].dt.quarter
    
    print("\n新增特征后的数据:")
    print(df.head())
    
    return df

# 探索性数据分析
def exploratory_analysis(df):
    print("\n=== 探索性数据分析 ===")
    
    # 1. 价格分布
    plt.figure(figsize=(15, 10))
    
    plt.subplot(2, 2, 1)
    plt.hist(df['price'], bins=20, alpha=0.7, color='skyblue', edgecolor='black')
    plt.title('房屋价格分布')
    plt.xlabel('价格(元)')
    plt.ylabel('频数')
    
    # 2. 面积分布
    plt.subplot(2, 2, 2)
    plt.hist(df['area'], bins=15, alpha=0.7, color='lightgreen', edgecolor='black')
    plt.title('房屋面积分布')
    plt.xlabel('面积(平方米)')
    plt.ylabel('频数')
    
    # 3. 各区平均价格
    plt.subplot(2, 2, 3)
    avg_price_by_location = df.groupby('location')['price'].mean().sort_values()
    avg_price_by_location.plot(kind='bar', color='orange', alpha=0.7)
    plt.title('各区平均房屋价格')
    plt.xlabel('区域')
    plt.ylabel('平均价格(元)')
    plt.xticks(rotation=45)
    
    # 4. 价格与面积关系
    plt.subplot(2, 2, 4)
    plt.scatter(df['area'], df['price'], alpha=0.6, color='purple')
    plt.title('房屋面积与价格关系')
    plt.xlabel('面积(平方米)')
    plt.ylabel('价格(元)')
    
    plt.tight_layout()
    plt.savefig('house_sales_analysis1.png', dpi=300, bbox_inches='tight')
    plt.show()
    
    # 5. 卧室数量对价格的影响
    plt.figure(figsize=(12, 5))
    
    plt.subplot(1, 2, 1)
    avg_price_by_bedrooms = df.groupby('bedrooms')['price'].mean()
    avg_price_by_bedrooms.plot(kind='bar', color='lightcoral', alpha=0.7)
    plt.title('卧室数量对平均价格的影响')
    plt.xlabel('卧室数量')
    plt.ylabel('平均价格(元)')
    plt.xticks(rotation=0)
    
    # 6. 每月销售情况
    plt.subplot(1, 2, 2)
    sales_by_month = df.groupby('month').size()
    sales_by_month.plot(kind='line', marker='o', color='blue', linewidth=2)
    plt.title('每月房屋销售数量')
    plt.xlabel('月份')
    plt.ylabel('销售数量')
    plt.xticks(range(1, 13))
    
    plt.tight_layout()
    plt.savefig('house_sales_analysis2.png', dpi=300, bbox_inches='tight')
    plt.show()

# 深入分析
def advanced_analysis(df):
    print("\n=== 深入分析 ===")
    
    # 1. 相关系数矩阵
    numeric_cols = ['area', 'bedrooms', 'bathrooms', 'age', 'price', 'price_per_sqm']
    correlation_matrix = df[numeric_cols].corr()
    
    print("数值变量相关系数矩阵:")
    print(correlation_matrix.round(2))
    
    # 热力图
    plt.figure(figsize=(10, 8))
    sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0,
                square=True, fmt='.2f', cbar_kws={'shrink': .8})
    plt.title('变量间相关系数热力图')
    plt.tight_layout()
    plt.savefig('correlation_heatmap.png', dpi=300, bbox_inches='tight')
    plt.show()
    
    # 2. 单价分析
    print("\n各区每平方米均价:")
    price_per_sqm_by_location = df.groupby('location')['price_per_sqm'].agg(['mean', 'std', 'count'])
    print(price_per_sqm_by_location.round(2))
    
    # 3. 房价预测模型(简单线性回归)
    from sklearn.linear_model import LinearRegression
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import mean_squared_error, r2_score
    
    # 选择特征和目标变量
    X = df[['area', 'bedrooms', 'bathrooms', 'age']]
    y = df['price']
    
    # 划分训练测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
    # 训练模型
    model = LinearRegression()
    model.fit(X_train, y_train)
    
    # 预测和评估
    y_pred = model.predict(X_test)
    
    print(f"\n模型评估结果:")
    print(f"R²分数: {r2_score(y_test, y_pred):.3f}")
    print(f"均方根误差: {np.sqrt(mean_squared_error(y_test, y_pred)):.2f}")
    
    # 特征重要性
    feature_importance = pd.DataFrame({
        'feature': X.columns,
        'coefficient': model.coef_,
        'abs_importance': abs(model.coef_)
    }).sort_values('abs_importance', ascending=False)
    
    print("\n特征重要性:")
    print(feature_importance)

# 销售趋势分析
def sales_trend_analysis(df):
    print("\n=== 销售趋势分析 ===")
    
    # 按周统计销售数量
    df['week'] = df['sale_date'].dt.isocalendar().week
    weekly_sales = df.groupby('week').size()
    
    plt.figure(figsize=(12, 5))
    
    plt.subplot(1, 2, 1)
    weekly_sales.plot(kind='line', marker='o', color='green', linewidth=2)
    plt.title('每周房屋销售趋势')
    plt.xlabel('周数')
    plt.ylabel('销售数量')
    plt.grid(True, alpha=0.3)
    
    # 按季度分析
    plt.subplot(1, 2, 2)
    quarterly_avg_price = df.groupby('quarter')['price'].mean()
    quarterly_avg_price.plot(kind='bar', color='lightblue', alpha=0.7)
    plt.title('各季度平均房屋价格')
    plt.xlabel('季度')
    plt.ylabel('平均价格(元)')
    plt.xticks(rotation=0)
    
    plt.tight_layout()
    plt.savefig('sales_trend_analysis.png', dpi=300, bbox_inches='tight')
    plt.show()

# 主函数
def main():
    try:
        # 加载和探索数据
        df = load_and_explore_data()
        
        # 数据清洗
        df_clean = clean_data(df)
        
        # 探索性分析
        exploratory_analysis(df_clean)
        
        # 深入分析
        advanced_analysis(df_clean)
        
        # 销售趋势分析
        sales_trend_analysis(df_clean)
        
        print("\n=== 分析完成 ===")
        print("已生成以下分析图表:")
        print("- house_sales_analysis1.png: 基础分布分析")
        print("- house_sales_analysis2.png: 卧室和月度销售分析")
        print("- correlation_heatmap.png: 相关系数热力图")
        print("- sales_trend_analysis.png: 销售趋势分析")
        
        # 保存处理后的数据
        df_clean.to_csv('cleaned_house_sales_data.csv', index=False, encoding='utf-8-sig')
        print("\n清洗后的数据已保存到: cleaned_house_sales_data.csv")
        
    except Exception as e:
        print(f"分析过程中出现错误: {e}")

if __name__ == "__main__":
    main()

数据样例(house_sales_data.csv):复制表格数据就行

house_id area(平方米) bedrooms(卧室数) bathrooms(卫生间数) location(区域) age(房龄) price(价格/元) sale_date(销售日期) sale_status(销售状态)
1 120 3 2 朝阳区 5 6500000 2025-01-15 已售
2 85 2 1 海淀区 8 4800000 2025-01-16 已售
3 150 4 3 西城区 3 9500000 2025-01-17 待售
4 95 2 2 东城区 12 5200000 2025-01-18 签约中
5 180 4 3 丰台区 2 8200000 2025-01-19 已售
6 110 3 2 朝阳区 7 6800000 2025-01-20 已售
7 75 1 1 海淀区 15 3500000 2025-01-21 待售
8 130 3 2 西城区 6 7800000 2025-01-22 已售
9 100 2 2 东城区 10 5500000 2025-01-23 签约中
10 160 4 3 丰台区 4 9200000 2025-01-24 已售
11 140 3 2 朝阳区 5 7200000 2025-01-25 待售
12 90 2 1 海淀区 9 4500000 2025-01-26 已售
13 170 4 3 西城区 2 9800000 2025-01-27 已售
14 105 3 2 东城区 8 5800000 2025-01-28 签约中
15 125 3 2 丰台区 3 7500000 2025-01-29 已售
16 155 4 3 朝阳区 4 8500000 2025-01-30 待售
17 80 2 1 海淀区 11 4200000 2025-01-31 已售
18 135 3 2 西城区 7 7900000 2025-02-01 已售
19 115 3 2 东城区 9 6200000 2025-02-02 签约中
20 145 4 3 丰台区 5 8800000 2025-02-03 已售

网站公告

今日签到

点亮在社区的每一天
去签到