YOLO813

根据已有资料分析北京2011-2016年房价

    以下数据源来自于互联网公开的北京二手房成交数据,仅作个人学习使用。
    目的:

  1.     分析北京二手房成交价格分布
  2.     寻找每个版块成交总金额超过1亿的经纪人
  3.     分析成交量超过1亿的经纪人相关因素


数据的读取与合并

    文件夹,一共有7份文件,所以肯定涉及到合并数据集,

data_list = []
for i in range(1,8):
    try:
        _ = pd.read_csv(f'./lianjia/lianjia{i}.csv')
    except:
        _ = pd.read_csv(f'./lianjia/lianjia{i}.csv',encoding='gbk')
    finally:
        data_list.append(_)
data = pd.concat(data_list)
data.head()


数据类型的转换

    可以看到数据的成交单价是*元/平,对数据分析并不友好,我们可以转换数据类型,让我们看的更加清楚。

    先来看下数据的各字段类型。

data.info()


    对数据某一列的处理,可以使用str的replace函数或者是Series的map函数,参考 数据清洗之字符串处理与应用函数处理数据

    先来看下第一种

round(data.cjdanjia.dropna().str.replace("元/平","").astype('float')/10000, 2)


    第二种方法

data.cjdanjia.dropna().map(lambda x:round(float(x.replace("元/平",""))/10000,1))

    看下最大值和最小值,最小值为0的不要

dj.max()
dj = dj[dj>0]


    此时,我们可以进行离散化分析了,

bins = [0,1,2,3,4,5,7,9,12,15]
pd.cut(dj,bins,right=False)

cats = pd.cut(dj,bins,right=False)
pd.value_counts(cats)

    我们还可以利用pandas绘图

pd.value_counts(cats).plot.bar(rot=30)


分组运算-寻找每个板块成交金额超过1亿的经纪人

    先来看下每个经纪人的总金额汇总

data.groupby('xingming')['cjzongjia'].sum()

    此时这个Series我们可以获得其布尔值

jiren_zongjia>10000

    但是需要注意的是,现在就不是在原来的data中取名字了,一开始我老是习惯使用data[jiren_zongjia>10000]来取值,结果报错:

IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match

大意就是这个布尔值数据的索引和原始数据索引不匹配!确实不匹配啊,因为布尔索引的取值经过了聚合,怎么可能会和原始数据源一致呢?正确的方法如下

jiren_zongjia[jiren_zongjia>10000]


    那么如何去获得每个板块中超过1亿金额的经纪人呢?这相当于两个聚合的问题,也是一样的解决方案

x = data.groupby(['bankuai','xingming'])['cjzongjia'].sum()
x

x[x>10000]

 

透视表-分析成交量超过1亿的经纪人相关因素

    透视表,动态的去改变表的布局,方便我们分析数据,比如说,重新去指定表的行或列。函数为pivot_table,先来看下它的介绍:

Create a spreadsheet-style pivot table as a DataFrame.
创建一个电子表格样式的数据透视表作为 DataFrame。

    相关参数:

Signature:
data.pivot_table(
    values=None,
    index=None,
    columns=None,
    aggfunc='mean',
    fill_value=None,
    margins=False,
    dropna=True,
    margins_name='All',
    observed=False,
    sort=True,
) -> 'DataFrame'

    第一个,即需要聚合的列

values : column to aggregate, optional

    第二个,index指定的索引

    第三个,columns指定的列名

    第四个,aggfunc指定对聚合数据应用的函数

    第五个,fill_value指定对缺失值应用的值

    先看下最简单的示例:

data.pivot_table(values='cjzongjia',index='xingming')

    

    稍微复杂一点的,想要筛选出所有经纪人的成交总金额和年份的关系:

data.pivot_table(values='cjzongjia',
                 index='xingming',
                 columns=['congyenianxian'],
                 aggfunc="sum")


    我们现在可以获取到经纪人的成交总金额是否超过1亿了

data_nx > 10000

    因为False在python中为0,True在python中为1,所以将每一列,例如1-2年、2-3年等等的数值相加,则可以获取从业年限1-2年,2-3年,3-4年等超过1亿的人数各有多少。

(data_nx > 10000).sum()
#等价于 np.sum(data_nx > 10000)

    因为sum函数默认是在轴0上进行计算,即计算行与行之间的和,所以不用修改axis值。


    照例,来个图形

np.sum(data_nx > 10000).plot.pie()

    可以看到matplotlib绘图无法显示中文标签,解决代码如下

from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
np.sum(data_nx > 10000).plot.pie()

 

对分组应用自定义函数

    先来看下数据,在聚合取值时,多一个中括号可以显示为DataFrame,如下面的第二种写法

data.groupby('bankuai')['cjdanjia'].mean()
data.groupby('bankuai')[['cjdanjia']].mean()

    假如我现在想要对均价进行排序,可以使用sort_values函数

data_1 = data.groupby('bankuai')[['cjdanjia']].mean()
data_1.sort_values(by='cjdanjia',ascending=False)

 

    现在假设有个需求,需求每个经纪人成交单价最高的前5套房子记录。之前在数据清洗之字符串处理与应用函数处理数据一文中介绍了DataFrame可以通过apply函数对行与列进行向量化处理,而data.groupby('xingming')是一个DataFrameGroupBy,也可以通过apply函数来应用自定义的函数。

def top(group, n=3):
    return group.sort_values(by = 'cjdanjia',ascending=False)[:n]
data.groupby('xingming').apply(top)

 

 

参考

https://www.cnblogs.com/onemorepoint/p/8425300.html