数据分析描述统计方法

描述统计的总结

统计量

# In[48]:均值

snd.price.mean()


# In[4]:中位数

snd.price.median()


# In[5]:标准差

snd.price.std()


# In[6]:偏度

snd.price.skew()


# In[16]:
snd.price.agg(['mean','median','sum','std','skew'])


# In[17]:分位数,这里取的是1%,50%,99%分位数

snd.price.quantile([0.01,0.5,0.99])
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import os
#get_ipython().magic('matplotlib inline')


# In[47]:
os.chdir(r'D:\pydata')
snd = pd.read_csv("sndHsPr.csv")


# In[54]: 将 price 和 AREA 列的数据相乘

snd["all_pr2"]=snd[["price","AREA"]].apply(lambda x:x[0]*x[1], axis = 1 )
snd.head()

# In[21]:

district = {'fengtai':'丰台区','haidian':'海淀区','chaoyang':'朝阳区','dongcheng':'东城区','xicheng':'西城区','shijingshan':'石景山区'}
snd['district'] = snd.dist.map(district)
# snd_new = snd.drop('dist',axis = 1)
snd.head()

# In[22]:

#snd.dist.value_counts()
snd.district.value_counts()
#type(snd.district.value_counts())
#snd.district.value_counts()/snd.district.count()

Out[6]: 
丰台区     2947
海淀区     2919
朝阳区     2864
东城区     2783
西城区     2750
石景山区    1947
Name: district, dtype: int64

一个分类变量 

# In[30]: 柱形图

#如遇中文显示问题可加入以下代码
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
snd.district.value_counts().plot(kind = 'bar')
#snd.district.value_counts().plot(kind = 'pie')  

一个连续变量 

# 直方图,bins=40 分 40 份
snd.price.hist(bins=40)

下面是分析两个变量之间的关系

# In[27]: district 为行,school 为列,python总是先行后列

sub_sch = pd.crosstab(snd.district,snd.school)
sub_sch

Out[15]: 
school       0     1
district            
东城区       1508  1275
丰台区       2853    94
朝阳区       2267   597
海淀区       1533  1386
石景山区      1929    18
西城区       1207  1543

分类柱形图 

# In[24]: 分类柱形图,district 作为横坐标,subway作为分类坐标

pd.crosstab(snd.district,snd.subway).plot(kind="bar")

堆叠柱形图(一般两个分类变量时用),分析不同的区教育资源(school)是否倾斜,但一般不用,用的是标准化的堆叠柱形图

# In[22]: 堆叠柱形图,stacked= True,主要用来比较某一个维度数据(这里为school)中不同类型数据(0和1)之间总数的差别

#pd.crosstab(snd.district,snd.school).plot(kind = 'bar')
t1=pd.crosstab(snd.district,snd.school)
t1.plot(kind = 'bar',stacked= True)

标准化的堆叠柱形图,比较占比情况

# In[38]: 标准化的堆叠柱形图,sum(1) 意思是汇总出一个列

sub_sch = pd.crosstab(snd.district,snd.school)
sub_sch["sum1"]=sub_sch.sum(1)
sub_sch.head()

Out[21]: 
school       0     1  sum1
district                  
东城区       1508  1275  2783
丰台区       2853    94  2947
朝阳区       2267   597  2864
海淀区       1533  1386  2919
石景山区      1929    18  1947


# In[29]: 每个值除以汇总的列,axis = 0,求出按行的百分比

sub_sch = sub_sch.div(sub_sch.sum1,axis = 0)
sub_sch

Out[22]: 
school           0         1  sum1
district                          
东城区       0.541861  0.458139   1.0
丰台区       0.968103  0.031897   1.0
朝阳区       0.791550  0.208450   1.0
海淀区       0.525180  0.474820   1.0
石景山区      0.990755  0.009245   1.0
西城区       0.438909  0.561091   1.0


# In[30]:

sub_sch[[0,1]].plot(kind = 'bar',stacked= True)

再进一步,通过柱的胖瘦比较数据量的大小

stack2dim.py

from pylab import mpl

mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题


def stack2dim(raw, i, j, rotation=0, location='upper right'):
    '''
    此函数是为了画两个维度标准化的堆积柱状图
    raw为pandas的DataFrame数据框
    i、j为两个分类变量的变量名称,要求带引号,比如"school"
    rotation:水平标签旋转角度,默认水平方向,如标签过长,可设置一定角度,比如设置rotation = 40
    location:分类标签的位置,如果被主体图形挡住,可更改为'upper left'
    '''
    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    import math

    data_raw = pd.crosstab(raw[i], raw[j])
    data = data_raw.div(data_raw.sum(1), axis=0)  # 交叉表转换成比率,为得到标准化堆积柱状图

    # 计算x坐标,及bar宽度
    createVar = locals()
    x = [0]  # 每个bar的中心x轴坐标
    width = []  # bar的宽度
    k = 0
    for n in range(len(data)):
        # 根据频数计算每一列bar的宽度
        createVar['width' + str(n)] = list(data_raw.sum(axis=1))[n] / sum(data_raw.sum(axis=1))
        width.append(createVar['width' + str(n)])
        if n == 0:
            continue
        else:
            k += createVar['width' + str(n - 1)] / 2 + createVar['width' + str(n)] / 2 + 0.05
            x.append(k)

    # 以下是通过频率交叉表矩阵生成一串对应堆积图每一块位置数据的数组,再把数组转化为矩阵
    y_mat = []
    n = 0
    y_level = len(data.columns)
    for p in range(data.shape[0]):
        for q in range(data.shape[1]):
            n += 1
            y_mat.append(data.iloc[p, q])
            if n == data.shape[0] * data.shape[1]:
                break
            elif n % y_level != 0:
                y_mat.extend([0] * (len(data) - 1))
            elif n % y_level == 0:
                y_mat.extend([0] * len(data))

    y_mat = np.array(y_mat).reshape(-1, len(data))
    y_mat = pd.DataFrame(y_mat)  # bar图中的y变量矩阵,每一行是一个y变量

    # 通过x,y_mat中的每一行y,依次绘制每一块堆积图中的每一块图

    from matplotlib import cm
    cm_subsection = [level for level in range(y_level)]
    colors = [cm.Pastel1(color) for color in cm_subsection]

    bottom = [0] * y_mat.shape[1]
    createVar = locals()
    for row in range(len(y_mat)):
        createVar['a' + str(row)] = y_mat.iloc[row, :]
        color = colors[row % y_level]

        if row % y_level == 0:
            bottom = bottom = [0] * y_mat.shape[1]
            if math.floor(row / y_level) == 0:
                label = data.columns.name + ': ' + str(data.columns[row])
                plt.bar(x, createVar['a' + str(row)],
                        width=width[math.floor(row / y_level)], label=label, color=color)
            else:
                plt.bar(x, createVar['a' + str(row)],
                        width=width[math.floor(row / y_level)], color=color)
        else:
            if math.floor(row / y_level) == 0:
                label = data.columns.name + ': ' + str(data.columns[row])
                plt.bar(x, createVar['a' + str(row)], bottom=bottom,
                        width=width[math.floor(row / y_level)], label=label, color=color)
            else:
                plt.bar(x, createVar['a' + str(row)], bottom=bottom,
                        width=width[math.floor(row / y_level)], color=color)

        bottom += createVar['a' + str(row)]

    plt.title(j + ' vs ' + i)
    group_labels = [str(name) for name in data.index]
    plt.xticks(x, group_labels, rotation=rotation)
    plt.ylabel(j)
    plt.legend(shadow=True, loc=location)
    plt.show()
# snd 为 DataFrame 类型,district 为连续变量, school为分类变量

from stack2dim import *

stack2dim(snd, i="district", j="school")

分类的堆叠面积图(别的数据集) 

#%%分类堆叠面积图

import matplotlib.pyplot as plt

labels=["青年卡","普通卡","金卡"]
y1=t1.loc[:,"青年卡"].astype('int')
y2=t1.loc[:,"普通卡"].astype('int')
y3=t1.loc[:,"金卡"].astype('int')
x=t1.index.astype('int')
plt.stackplot(x,y1,y2,y3,labels = labels)
plt.title('发卡趋势')
plt.ylabel('发卡量')
plt.legend(loc = 'upper left')
plt.show()

 

一个分类变量,一个连续变量,groupby(分类变量) 分组然后对连续变量求统计量

snd.price.groupby(snd.district).mean().plot(kind="bar")

条形图

snd.price.groupby(snd.district).mean().sort_values(ascending= True).plot(kind = 'barh')

分类盒须图(一般一个分类变量,一个连续变量时用)

sns.boxplot(x = 'district', y = 'price', data = snd)

西城区中位数最高,丰台区房价更集中,西城区差异更大 

作多个图(使用的是别的数据集)

import seaborn as sns
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
sns.boxplot(x='loss_flag', y='Age', data=ins,ax=ax1)
sns.boxplot(x='loss_flag', y='exp', data=ins,ax=ax2)

 

两个分类变量,一个连续变量

snd.pivot_table(values='price', index='district', columns='school', aggfunc=np.mean)

Out[26]: 
school               0             1
district                            
东城区       66276.887931  78514.900392
丰台区       42291.003505  48871.617021
朝阳区       51588.511689  57403.405360
海淀区       61385.803653  76911.258297
石景山区      40353.883878  33107.333333
西城区       76989.369511  92468.873623
snd.pivot_table(values='price', index='district', columns='school', aggfunc=np.mean).plot(kind = 'bar')

两个连续变量

# 散点图
snd.plot.scatter(x = 'AREA', y = 'price')

时间与两个连续变量,双轴图

import mathplotlib.pyplot as plt

gdp = pd.read_csv('gdp_gdpcr.csv',encoding = 'gbk')
gdp.head()
# In[45]:

x = list(gdp.year)
GDP = list(gdp.GDP)
# GDP 增长率
GDPCR = list(gdp.GDPCR)
fig = plt.figure()

ax1 = fig.add_subplot(111)
ax1.bar(x,GDP)
ax1.set_ylabel('GDP')
ax1.set_title("GDP of China(2000-2017)")
ax1.set_xlim(2000,2017)

# 复制主轴 y
ax2 = ax1.twinx()
# 颜色 red
ax2.plot(x,GDPCR,'r')
ax2.set_ylabel('Increase Ratio')
ax2.set_xlabel('Year')

制图原理

  • 第一步 明确你要表达的信息
  • 第二步 确定相对关系
  • 第三步 选择图表形式

  • “条图”与“柱图”具有细微的差异,两个图形经常回
    混用。
  • “双轴图”由于存在两个Y轴,容易被混淆,所以广被
    病垢。R的专业绘图包ggplot中甚至明确的提出不支持
    双轴图。其实“双轴图”在使用中有其特殊的用途和约
    定俗成的使用情景。其中的X轴为时间,左Y轴为指标
    水平(也称作绝对量,比如GDP)的刻度,右Y轴为指标
    增长率(也称作变化率,比如GDP增长率)。而且用柱
    形代表水平,用线形代表增长率。

猜你喜欢

转载自blog.csdn.net/HAIYUANBOY/article/details/89451266
今日推荐