定义目标
通过20,050,143数据进行分析,一个单表,其中列有:姓名:'Name'、证件类型:'CtfTp'、证件号:'CtfId'、性别:'Gender' 、生日:'Birthday'、手机号:'Mobile'、邮箱:'EMail'
分析的目标有:
-
性别分布
- 省份人口分布
- 年龄分布
- 生日月份分布
- 星座分布
- 生肖分布
- 手机号运营商
- 手机尾号喜爱
- 姓氏分析
- 男性尾名
- 女性尾名
- 邮箱偏爱
数据收集
现有2012年历史开房数据,无需抓取。
数据处理
数据处理主要包括数据清洗、数据转化、数据抽取、数据合并、数据计算等处理方法,将各种原始数据加工成为数据分析所要求的样式。数据处理是数据分析最耗时一个过程,数据处理都是在mysql数据库通过sql语句进行处理的。
- 删除一些无用信息,比如姓名、证件号、性别同时为空的一些垃圾数据;
- 性别为空或其他值的记录,有身份证信息的通过证件号信息进行补充;无证件号的设置为UNKNOW值;
- 生日为空或其他值的记录,有身份证信息的通过证件号信息进行补充;无证件号的设置为19000101;
- 如果是身份证号,号码不符合15位或18位身份证规则的数据,如果其他列数据有效,则保留;否则删除;
注:
15位身份证号码各位的含义:
1-2位省、自治区、直辖市代码;
3-4位地级市、盟、自治州代码;
5-6位县、县级市、区代码;
7-12位出生年月日,比如370201代表1937年2月1日;
13-15位为顺序号,其中第15位男为单数,女为双数。
举例:
130503 370201 001的含义; 13为河北,05为邢台,03为桥西区,出
生日期为1937年2月1日,性别男。
18位身份证号码的含义:
1-2位省、自治区、直辖市代码;3-4位地级市、盟、自治州代码;5-6位县、县级市、区代码;
7-14位出生年月日,比如19370201代表1937年2月1日;15-17位为顺序号,
其中17位(倒数第二位)男为单数,女为双数;
举例:
130503 19370201 0112的含义; 13为河北,05为邢台,03为桥西区,出
生日期为1937年2月1日,性别男。
数据分析
经过数据处理后,还有19,704,000条记录,不到2000万条,并存入csv文件,有些直接查mysql分析统计,有些需要通过csv文件分析统计
一、性别分布
通过对性别列groupby进行统计,最后统计男性有12,722,240条,占比64.57%,女性有6,932,750条,占比35.18%,未知性别有49,198条,占比0.25%,虽然男性比女性多了20个百分点,但是也反映了女性快要占据半边天了。
统计代码:
# coding: utf-8
import numpy as np
from pandas import Series, DataFrame
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
a = datetime.now()
totalStartTime=datetime.now()
#总数统计
allCount = 0;
# 性别统计
sexCount = 0;
# 男女统计
maleCount = 0
femaleCount = 0
unknowCount = 0
chunksize = 10 **6
for dataDF in pd.read_csv("e:\\data\\2000w.csv", chunksize=chunksize):
print("------------------------------")
# 查看每一列数据统计数目
dataDFCount = dataDF.count()
# print(dataDFCount)
#总数统计id记录统计
allCount = allCount + dataDFCount[0]
#性别总数统计
sexCount = sexCount + dataDFCount[4]
genderCount = dataDF['id'].groupby(dataDF['Gender'])
print(genderCount.count())
print("本次总数:"+str(dataDFCount[4])+" 总数:" +str(sexCount))
femaleCount = femaleCount +genderCount.count()['F']
print("本次女总数:"+str(genderCount.count()['F'])+" 女总数:"+ str(femaleCount))
maleCount = maleCount +genderCount.count()['M']
print("本次男总数:"+str(genderCount.count()['M'])+" 男总数:"+ str(maleCount))
unknowCount = unknowCount + genderCount.count()['UNKWON']
print("本次UNKWON总数:" + str(genderCount.count()['UNKWON']) + " UNKWON总数:" + str(unknowCount))
print("------------------------------")
b=datetime.now()
print("耗时:"+str((b-a).seconds)+"秒")
a = datetime.now()
totalEndTime=datetime.now()
print("总耗时:"+str((totalEndTime-totalStartTime).seconds))
print("性别列总数:" + str(sexCount) + ",男总数:" + str(maleCount) + ",女总数:" + str(femaleCount)+ ",unknowCount总数:" + str(unknowCount))
数据展现代码:
import matplotlib.pyplot as plt
import re
plt.rcParams['font.sans-serif']=['SimHei']
# 饼状图标签
quants = []
#男性总数
maleCount = 12722240
#女性总数
femaleCount = 6932750
#未知性别总数
unknowCount = 49198
quants.append(float(maleCount))
quants.append(float(femaleCount))
quants.append(float(unknowCount))
plt.figure(figsize=(6,6)) #调节图形大小
labels = [u'男性',u'女性',u'未知'] #定义标签
sizes = [maleCount,femaleCount,unknowCount] #每块值
#colors = ['red','yellowgreen','lightskyblue','yellow'] #每块颜色定义
explode = (0,0,0) #将某一块分割出来,值越大分割出的间隙越大
patches,text1,text2 = plt.pie(sizes,
explode=explode,
labels=labels,
# colors=colors,
labeldistance = 1.2,#图例距圆心半径倍距离
autopct = '%3.2f%%', #数值保留固定小数位
shadow = True, #无阴影设置
startangle =90, #逆时针起始角度设置
pctdistance = 0.6) #数值距圆心半径倍数距离
#patches饼图的返回值,texts1饼图外label的文本,texts2饼图内部文本
#标题
# plt.title('男女比例', bbox={'facecolor':'0.6', 'pad':15})
# x,y轴刻度设置一致,保证饼图为圆形
plt.axis('equal')
plt.legend()
plt.show()
数据展现图(饼状图)如下:
二、省份人口分布
通过对身份证前两位编码进行分组,人口总数最多的前四个省份是江苏(241万)、山东(153万)、浙江(135万)、河南(112万),从GDP和人口数量判断,这三个省份占比大合情合理,但是广东从GDP和人口数量来说不应该排后,总人口才56万,看来数据源没有正常覆盖到广东。
统计及数据展现代码:
# coding: utf-8
import numpy as np
from pandas import Series, DataFrame
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.ticker import FuncFormatter
a = datetime.now()
totalStartTime=datetime.now()
#总数统计
allCount = 0;
chunksize = 10 **6
# columnList = ['id','Name','CtfTp','CtfId','Gender','Birthday','Mobile','EMail']
areaList = ['11','12','13','14','15','21','22','23','31','32','33','34','35','36','37','41','42','43','44','45','46','50','51','52','53','54','61','62','63','64','65']
areaNameList = ['北京','天津','河北','山西','内蒙古','辽宁','吉林','黑龙江','上海','江苏','浙江','安徽','福建','江西','山东','河南','湖北','湖南','广东','广西','海南','重庆','四川','贵州','云南','西藏','陕西','甘肃','青海','宁夏','新疆']
areaAllSeries = pd.Series([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
areaAllSeries.index = areaList
# 计数器
i = 0
for dataDF in pd.read_csv("e:\\data\\2000w.csv", chunksize=chunksize):
#dataframe合并方法,各个值累加
# allDF = pd.concat([allDF, dataDF], ignore_index=False)
#筛选数据集CtfTp为ID并且CtfId值前两位在地区编码中的