pandas数据探索(独创)

使用 Pandas 进行数据探索

本次实验通过分析电信运营商的客户离网率数据集来熟悉 Pandas 数据探索的常用方法,并构建一个预测客户离网率的简单模型。

Pandas 的主要方法

Pandas 是基于 NumPy 的一种工具,提供了大量数据探索的方法。Pandas 可以使用类似 SQL 的方式对 .csv、.tsv、.xlsx 等格式的数据进行处理分析。
Pandas 主要使用的数据结构是 Series 和 DataFrame 类。下面简要介绍下这两类:
Series 是一种类似于一维数组的对象,它由一组数据(各种 NumPy 数据类型)及一组与之相关的数据标签(即索引)组成。
DataFrame 是一个二维数据结构,即一张表格,其中每列数据的类型相同。你可以把它看成由 Series 实例构成的字典。

  1. 首先载入必要的库,即 NumPy 和 Pandas。
    import numpy as np
    import pandas as pd
    import warnings
    warnings.filterwarnings(“ignore”)
    通过 read_csv() 方法读取数据,然后使用 head() 方法查看前 5 行数据:
    df=pd.read_csv(‘https://labfile.oss.aliyuncs.com/courses/1283/telecom_churn.csv’)
    df.head()
    在这里插入图片描述
    上图中的每行对应一位客户,每列对应客户的一个特征。
    让我们查看一下该数据库的维度、特征名称和特征类型。
    在这里插入图片描述
    上述结果表明,我们的列表包含 3333 行和 20 列。下面我们尝试打印列名。
    df.columns
    在这里插入图片描述
    我们还可以使用 info() 方法输出 DataFrame 的一些总体信息:
    df.info()
    在这里插入图片描述
    bool、int64、float64 和 object 是该数据库特征的数据类型。这一方法同时也会显示是否有缺失值,上述结果表明在该数据集中不存在缺失值,因为每列都包含 3333 个观测,和我们之前使用 shape 方法得到的数字是一致的。
    astype() 方法可以更改列的类型,下列公式将 Churn 离网率 特征修改为 int64 类型:
    df[‘Churn’]=df[‘Churn’].astype(‘int64’)
    describe() 方法可以显示数值特征(int64 和 float64)的基本统计学特性,如未缺失值的数值、均值、标准差、范围、四分位数等。
    df.describe()
    在这里插入图片描述
    通过 include 参数显式指定包含的数据类型,可以查看非数值特征的统计数据。
    df.describe(include=[‘object’,‘bool’])
    在这里插入图片描述
    value_counts() 方法可以查看类别(类型为 object )和布尔值(类型为 bool )特征。让我们看下 Churn 离网率 的分布。
    df[‘Churn’].value_counts()
    在这里插入图片描述
    上述结果表明,在 3333 位客户中, 2850 位是忠实客户,他们的 Churn 值为 0。调用 value_counts() 函数时,加上 normalize=True 参数可以显示比例
    df[‘Churn’].value_counts(normalize=True)
    在这里插入图片描述

排序

DataFrame 可以根据某个变量的值(也就是列)排序。比如,根据每日消费额排序(设置 ascending=False 倒序排列)
\df.sort_values(by=‘Total day charge’,ascending=False).head()
在这里插入图片描述
此外,还可以根据多个列的数值排序。下面函数实现的功能为:先按 Churn 离网率 升序排列,再按 Total day charge 每日总话费 降序排列,优先级 Churn > Tatal day charge。
df.sort_values(by=[‘Churn’,‘Total day charge’],ascending=[True,False]).head()
在这里插入图片描述

索引和获取数据

DataFrame 可以以不同的方式进行索引。
使用 DataFrame[‘Name’] 可以得到一个单独的列。比如,离网率有多高?
df[‘Churn’].mean()
在这里插入图片描述
对一家公司而言,14.5% 的离网率是一个很糟糕的数据,这么高的离网率可能导致公司破产。

布尔值索引同样很方便,语法是 df[P(df[‘Name’])],P 是在检查 Name 列每个元素时所使用的逻辑条件。这一索引的输出是 DataFrame 的 Name 列中满足 P 条件的行。

让我们使用布尔值索引来回答这样以下问题:离网用户的数值变量的均值是多少?
df[df[‘Churn’]==1].mean()
在这里插入图片描述
离网用户在白天打电话的总时长的均值是多少?
df[df[‘Churn’] == 1][‘Total day minutes’].mean()在这里插入图片描述
未使用国际套餐(International plan == NO)的忠实用户(Churn == 0)所打的最长的国际长途是多久?
df[(df[‘Churn’] == 0) & (df[‘International plan’] == ‘No’)
][‘Total intl minutes’].max()
在这里插入图片描述
DataFrame 可以通过列名、行名、行号进行索引。loc 方法为通过名称索引,iloc 方法为通过数字索引。

通过 loc 方法输出 0 至 5 行、State 州 至 Area code 区号 的数据。
df.loc[0:5, ‘State’:‘Area code’]在这里插入图片描述
通过 iloc 方法输出前 5 行的前 3 列数据(和典型的 Python 切片一样,不含最大值)
df.iloc[0:5, 0:3]在这里插入图片描述
df[:1] 和 df[-1:] 可以得到 DataFrame 的首行和末行。
df[-1:]
在这里插入图片描述

应用函数到单元格、列、行

下面通过 apply() 方法应用函数 max 至每一列,即输出每列的最大值。
df.apply(np.max)
在这里插入图片描述
apply() 方法也可以应用函数至每一行,指定 axis=1 即可。在这种情况下,使用 lambda 函数十分方便。比如,下面函数选中了所有以 W 开头的州。
df[df[‘State’].apply(lambda state: state[0] == ‘W’)].head()在这里插入图片描述
map() 方法可以通过一个 {old_value:new_value} 形式的字典替换某一列中的值。
d = {‘No’: False, ‘Yes’: True}
df[‘International plan’] = df[‘International plan’].map(d)
df.head()
在这里插入图片描述
当然,使用 repalce() 方法一样可以达到替换的目的。
df = df.replace({‘Voice mail plan’: d})
df.head()
在这里插入图片描述

分组(Groupby)

Pandas 下分组数据的一般形式为

df.groupby(by=grouping_columns)[columns_to_show].function()

对上述函数的解释:
groupby() 方法根据 grouping_columns 的值进行分组。
接着,选中感兴趣的列(columns_to_show)。若不包括这一项,那么就会选中所有非 groupby 列(即除 grouping_colums 外的所有列)。
最后,应用一个或多个函数(function)。
在下面的例子中,我们根据 Churn 离网率 变量的值对数据进行分组,显示每组的统计数据。
columns_to_show = [‘Total day minutes’, ‘Total eve minutes’,
‘Total night minutes’]

df.groupby([‘Churn’])[columns_to_show].describe(percentiles=[])
在这里插入图片描述
和上面的例子类似,只不过这次将一些函数传给 agg(),通过 agg() 方法对分组后的数据进行聚合。
columns_to_show = [‘Total day minutes’, ‘Total eve minutes’,
‘Total night minutes’]

df.groupby([‘Churn’])[columns_to_show].agg([np.mean, np.std, np.min, np.max])
在这里插入图片描述

汇总表

Pandas 中的透视表定义如下:

透视表(Pivot Table)是电子表格程序和其他数据探索软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组将数据分配到各个矩形区域中。

通过 pivot_table() 方法可以建立透视表,其参数如下:

values 表示需要计算的统计数据的变量列表
index 表示分组数据的变量列表
aggfunc 表示需要计算哪些统计数据,例如,总和、均值、最大值、最小值等
现在,通过 pivot_table() 方法查看不同区号下白天、夜晚、深夜的电话量的均值
df.pivot_table([‘Total day calls’, ‘Total eve calls’, ‘Total night calls’], [‘Area code’], aggfunc=‘mean’)在这里插入图片描述
交叉表(Cross Tabulation)是一种用于计算分组频率的特殊透视表,在 Pandas 中一般使用 crosstab() 方法构建交叉表
构建一个交叉表查看样本的 Churn 离网率 和 International plan 国际套餐 的分布情况。
pd.crosstab(df[‘Churn’], df[‘International plan’])
在这里插入图片描述
构建一个交叉表查看 Churn 离网率 和 Voice mail plan 语音邮件套餐 的分布情况
pd.crosstab(df[‘Churn’], df[‘Voice mail plan’], normalize=True)在这里插入图片描述
上述结果表明,大部分用户是忠实用户,同时他们并不使用额外的服务(国际套餐、语音邮件)。

增减 DataFrame 的行列

在 DataFrame 中新增列有很多方法,比如,使用 insert()方法添加列,为所有用户计算总的 Total calls 电话量。
total_calls = df[‘Total day calls’] + df[‘Total eve calls’] +
df[‘Total night calls’] + df[‘Total intl calls’]

loc 参数是插入 Series 对象后选择的列数

设置为 len(df.columns)以便将计算后的 Total calls 粘贴到最后一列

total_calls = df[‘Total day calls’] + df[‘Total eve calls’] +
df[‘Total night calls’] + df[‘Total intl calls’]

loc 参数是插入 Series 对象后选择的列数

设置为 len(df.columns)以便将计算后的 Total calls 粘贴到最后一列

total_calls = df[‘Total day calls’] + df[‘Total eve calls’] +
df[‘Total night calls’] + df[‘Total intl calls’]
df.insert(loc=len(df.columns), column=‘Total calls’, value=total_calls)
df.head()
上面的代码创建了一个中间 Series 实例,即 tatal_calls,其实可以在不创造这个实例的情况下直接添加列。
df[‘Total charge’] = df[‘Total day charge’] + df[‘Total eve charge’] +
df[‘Total night charge’] + df[‘Total intl charge’]
df.head()在这里插入图片描述
使用 drop() 方法删除列和行。
df.drop([‘Total charge’, ‘Total calls’], axis=1, inplace=True)
df.drop([1, 2]).head()在这里插入图片描述
对上述代码的部分解释:

将相应的索引 [‘Total charge’, ‘Total calls’] 和 axis 参数(1 表示删除列,0 表示删除行,默认值为 0)传给 drop。
inplace 参数表示是否修改原始 DataFrame (False 表示不修改现有 DataFrame,返回一个新 DataFrame,True 表示修改当前 DataFrame)。

预测离网率

首先,通过上面介绍的 crosstab() 方法构建一个交叉表来查看 International plan 国际套餐 变量和 Churn 离网率 的相关性,同时使用 countplot() 方法构建计数直方图来可视化结果。
import matplotlib.pyplot as plt
import seaborn as sns
sns.countplot(x=‘International plan’, hue=‘Churn’, data=df)
在这里插入图片描述
上图表明,开通了国际套餐的用户的离网率要高很多,这是一个很有趣的观测结果。也许,国际电话高昂的话费让客户很不满意。
同理,查看 Customer service calls 客服呼叫 变量与 Chunrn 离网率 的相关性,并可视化结果。
pd.crosstab(df[‘Churn’], df[‘Customer service calls’], margins=True)在这里插入图片描述
sns.countplot(x=‘Customer service calls’, hue=‘Churn’, data=df)在这里插入图片描述
上图表明,在客服呼叫 4 次之后,客户的离网率显著提升。
为了更好的突出 Customer service call 客服呼叫 和 Churn 离网率 的关系,可以给 DataFrame 添加一个二元属性 Many_service_calls,即客户呼叫超过 3 次(Customer service calls > 3)。看下它与离网率的相关性,并可视化结果。
df[‘Many_service_calls’] = (df[‘Customer service calls’] > 3).astype(‘int’)

pd.crosstab(df[‘Many_service_calls’], df[‘Churn’], margins=True)在这里插入图片描述
sns.countplot(x=‘Many_service_calls’, hue=‘Churn’, data=df)在这里插入图片描述
现在我们可以创建另一张交叉表,将 Churn 离网率 与 International plan 国际套餐 及新创建的 Many_service_calls 多次客服呼叫 关联起来
pd.crosstab(df[‘Many_service_calls’] & df[‘International plan’], df[‘Churn’])在这里插入图片描述
上表表明,在客服呼叫次数超过 3 次并且已办理 International Plan 国际套餐 的情况下,预测一名客户不忠诚的准确率(Accuracy)可以达到 85.8%,计算公式如下:
在这里插入图片描述
其中,TP 表示将 True 预测为 True 的数量,TN 表示将 Flase 预测为 Flase 的数量,FP 表示将 Flase 预测为 True 的数量,FN 表示将 True 预测为 Flase 的数量。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刹那永恒HB

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值