pandas统计各个城市的平均房价

pandas统计各个城市的平均房价

上一次使用scrapy框架爬取到全国房价,今天我便想使用pandas来统计出陕西省各个城市的房价并利用matplotlib进行数据展示。
首先,在pandas模块中提供了很方便地从mysql数据库中读取数据,方法如下:

def __init__(self):
    '''从数据库读取房价信息'''
    self.conn = pymysql.connect(host = 'localhost',
                           user = 'root',
                           passwd = 'root',
                           db = 'fang',
                           charset = 'utf8')
    sql_query = 'select * from fang.fang_info'
    self.df = pd.read_sql(sql_query, con=self.conn)
    # print(df.head(10))
    # print(df.info())

读取到数据后按照name属性进行数据的去重:df_shanxi_info = df_shanxi.drop_duplicates('name')
分析数据:由于只需要统计平均房价,所以读取到的房源信息中只需要关注‘price’这一列,其它的不做考虑。而在‘price’中有这几种:4100元/㎡、价格待定往期3800元/㎡、价格待定、价格待定周边6066元/㎡、259万元/套等且都是字符串。

1. 由于259万元/套类型的房子很少且对整个的数据分析结果不会造成大的影响,所以有/套的行可以舍去。pandas中提供了一种方法isin():isin()接受一个列表,判断该列中元素是否在列表中,反函数就是在前面加上 ~。示例代码如下:
# 取出所有不包含'/套'的数据
df_shanxi_info = df_shanxi_info[~(df_shanxi_info['price'].map(lambda x:x.split('/')[-1]).isin(['套']))]
2.对于其它的,由于是字符串,所以不能对其进行求平均值,而且其含有中文和其他符号,所以也不能对其强制类型转换。解决方法:
  • 可以使用replace函数进行过滤:df.replace(to_replace, value) 前面是需要替换的值,后面是替换后的值。对于多个条件可以写为:df.replace(to_replace, value).replace(to_replace, value).replace(to_replace, value).replace(to_replace, value)
    但是由于price中需要替换的元素太多而且不确定,所以在这里我使用了另外一种方式,也是十分方便的方法----->正则表达式
  • str.extract(),可用正则从字符数据中抽取匹配的数据,只返回第一个匹配的数据。
    str.extract(pat, flags=0, expand=None)参数: pat : 字符串或正则表达式 flags : 整型, expand : 布尔型,是否返回DataFrame 。示例代码如下:
# 只提取价格中的数字 3000元/㎡------->3000
self.df['price_num'] = df_shanxi_info['price'].str.extract(r'(\d+)', flags=0, expand=False).astype('float64')
  • 在提取到price中想要的数据后便可以将其与原来的数据进行合并:
    join:默认情况下把行索引相同的数据合并到一起,例如:
    在这里插入图片描述
  • 完成之后数据中会有NaN数据,进行处理:df_shanxi_info = df_shanxi_info[pd.notnull(self.df['price_num'])]
  • 然后按照城市分组求每个城市的平均价格:
# 按照城市分组求每个城市的平均价格
shanxi_grouped = self.df['price_num'].groupby(df_shanxi_info['city']).mean().sort_values(ascending=False)

得到的是一个 **‘pandas.core.series.Series’**类型的数据

  • 至此,数据的清洗、过滤等工作已经完成,为了更好地呈现出数据,我利用了python中的matplotlib模块进行绘图展示:如下:
fig = plt.figure(figsize=(20, 8), dpi=80)
my_font = font_manager.FontProperties(fname="C:/WINDOWS/FONTS/SIMHEI.TTF", size=20)
text_font = font_manager.FontProperties(fname="C:/WINDOWS/FONTS/MSYHL.TTC", size=50)
_x = range(len(shanxi_grouped.index))
_y = shanxi_grouped.values

plt.bar(_x, _y, width=0.2, color='blue')
plt.xticks(_x, shanxi_grouped.index, fontproperties=my_font, size=13)
plt.xlabel('城市', fontproperties=my_font, color='orange')
plt.ylabel('平均房价(元/㎡)', fontproperties=my_font, color='orange')
plt.title('陕西省各个城市的平均房价统计', fontproperties=my_font, color='orange')

程序完整代码:

import pymysql
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib import font_manager

class Fang():
    def __init__(self):
        '''从数据库读取房价信息'''
        self.conn = pymysql.connect(host = 'localhost',
                               user = 'root',
                               passwd = 'root',
                               db = 'fang',
                               charset = 'utf8')
        sql_query = 'select * from fang.fang_info'
        self.df = pd.read_sql(sql_query, con=self.conn)
        # print(df.head(10))
        # print(df.info())

    def extract_shanxi(self):
        '''选取陕西省的房价信息'''
        df_shanxi = self.df[(self.df['province'] == '陕西')]

        # 去掉重复信息
        df_shanxi_info = df_shanxi.drop_duplicates('name')
        # 取出所有不包含'/套'的数据
        df_shanxi_info = df_shanxi_info[~(df_shanxi_info['price'].map(lambda x:x.split('/')[-1]).isin(['套']))]
        # 只提取价格中的数字 3000元/㎡------->3000并与之前的数据合并
        self.df['price_num'] = df_shanxi_info['price'].str.extract(r'(\d+)', flags=0, expand=False).astype('float64')
        df_shanxi_info = df_shanxi_info.join(self.df['price_num'])
        df_shanxi_info = df_shanxi_info[pd.notnull(self.df['price_num'])]

        # 按照城市分组求每个城市的平均价格
        shanxi_grouped = self.df['price_num'].groupby(df_shanxi_info['city']).mean().sort_values(ascending=False)
        print(type(shanxi_grouped))

        self.conn.close()
        return shanxi_grouped

    def draw_fang(self, shanxi_grouped):
        '''画图'''
        fig = plt.figure(figsize=(20, 8), dpi=80)
        my_font = font_manager.FontProperties(fname="C:/WINDOWS/FONTS/SIMHEI.TTF", size=20)
        text_font = font_manager.FontProperties(fname="C:/WINDOWS/FONTS/MSYHL.TTC", size=50)
        _x = range(len(shanxi_grouped.index))
        _y = shanxi_grouped.values

        plt.bar(_x, _y, width=0.2, color='blue')
        plt.xticks(_x, shanxi_grouped.index, fontproperties=my_font, size=13)
        plt.xlabel('城市', fontproperties=my_font, color='orange')
        plt.ylabel('平均房价(元/㎡)', fontproperties=my_font, color='orange')
        plt.title('陕西省各个城市的平均房价统计', fontproperties=my_font, color='orange')

        # 网格
        plt.grid(linestyle="--", alpha=0.4)
        # 水印
        fig.text(x=0.4,
                 y=0.7,
                 s='好吃的小西红柿',
                 color='gray',
                 fontproperties=text_font,
                 rotation=45,
                 alpha=0.2)

        plt.savefig('./fang.png')
        plt.show()

    def run(self):
        shanxi_grouped = self.extract_shanxi()
        self.draw_fang(shanxi_grouped)


if __name__ == '__main__':
    fang = Fang()
    fang.run()

数据展示:
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值