python练手分析2000万开房数据

该博客通过Python分析2000万条开房数据,揭示了性别比例(男性占比64.57%)、省份人口分布(江苏、山东、浙江、河南居前)、年龄结构(80后为主力军)。数据处理涉及数据清洗、转化和计算,使用SQL在MySQL中进行。分析结果显示,男性比女性多,但女性占比接近35%,反映出女性影响力增长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义目标

通过20,050,143数据进行分析,一个单表,其中列有:姓名:'Name'、证件类型:'CtfTp'、证件号:'CtfId'、性别:'Gender' 、生日:'Birthday'、手机号:'Mobile'、邮箱:'EMail'

分析的目标有:

  1. 性别分布

  2. 省份人口分布
  3. 年龄分布
  4. 生日月份分布
  5. 星座分布
  6. 生肖分布
  7. 手机号运营商
  8. 手机尾号喜爱
  9. 姓氏分析
  10. 男性尾名
  11. 女性尾名
  12. 邮箱偏爱

数据收集

现有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值前两位在地区编码中的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值