五、Python数据挖掘(Pandas高级处理)

五、Python数据挖掘(Pandas高级处理)


一、Nan 缺失值处理

回顾:在 Numpy库 中介绍到,当读取的数据文件中包含 空格 或一些 字符串 时就可能会出现缺失值 NaN

处理思路:

  • 删除含有缺失值的样本
  • 替换/插补缺失值,如:平均值替换

具有一定的复杂程度,在 Pandas 中就较为容易

判断是否为缺失值 NaN

pd.isnull(DataFrame数组)
DataFrame数组.isnull()

上述两种调用方式都可以
判断 DataFrame数组 中是否为缺失值,是则对应位置为 True ,否则对应位置为 False

pd.notnull(DataFrame数组)
DataFrame数组.notnull()

上述两种调用方式都可以
判断 DataFrame数组 中是否有值,是则对应位置为 True ,否则对应位置为 False

例:快速判断一个 DataFrame数组 中是否存在缺失值:

np.any() 配合 pd.isnull() 的方式,判断是否存在缺失值
在这里插入图片描述
判断列是否含有缺失值
在这里插入图片描述
np.all() 配合 pd.notnull() 的方式,判断是否都有值
在这里插入图片描述
判断列是否都有值
在这里插入图片描述

1.处理方式——删除:

DataFrame数组.dropna(axis=“rows”, inplace=False)

把含有缺失值 NaN 的行删除
axis=“rows” 时,会删除含缺失值 NaN 的行,axis 默认为 rows
axis=“columns” 时,会删除含缺失值 NaN 的列
inplace=True 时,会直接在原 DataFrame数组 上进行修改
inplace=False 时,会返回一个删除含 NaN 行的新数组,不会修改 DataFrame数组inplace 默认为 False

例:
在这里插入图片描述

2.处理方式——替换:

DataFrame数组.fillna(value, inplace)

DataFrame数组 中的缺失值 NaN 统一修改为 value
value 统一修改后的值
inplace=True 时,会直接在原 DataFrame数组 上进行修改
inplace=False 时,会返回一个修改后的新数组,不会修改 DataFrame数组inplace 默认为 False

例:分别替换为各列对应的平均值
在这里插入图片描述


二、其他类型缺失值处理

缺失值可能不是 NaN,可能是其他标记值,如:?

此时,我们需要把 ? 替换为 np.nan ——即 NaN 缺失值类型,再对 NaN 缺失值进行处理

DataFrame数组.replace(to_replace=" ", value=np.nan)

把是 to_replace 的值全部替换为 value
to_replace=" " 是需要替换的值,如:to_replace="?"
value= 是替换成的值,如:value=np.nan,替换成 NaN 缺失值


三、数据离散化
1.数据类别处理

一般来说,事物的属性可能并不完全能够使用数字来表示,如:性别男或女,毛发的颜色等等......

以性别为例,如果以数字代表男女,如:1-男、2-女,但是计算机并不懂得这一数字的含义,以计算机的角度来看,计算机知道只知道这是两个数字,并且它们具有大小排名,但是性别属性是不应该具有大小排名之分的,这样带来的影响并不好,如何处理这些数据呢?

处理思路:额外增加其他属性,符合时为1,不符合时为0即可
在这里插入图片描述

2.数据离散化

连续属性的离散化就是将连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数值代表落在每个子区间中的属性值

比如说:以身高为例

数据
height = [165, 174, 160, 180, 159, 163, 192, 184]

离散化
在这里插入图片描述
连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。离散化方法经常作为数据挖掘的工具

3.Panda 实现数据离散化
(1)分组

自动分组

sr = pd.qcut(data, bins)

实现自动分组
data 需要分组的数据
bins 要分成的组数
返回值 返回一个 Series 数组

sr = pd.cut(data, [ ])

data 需要分组的数据
[ ] 设定的分组区间,这里输入是所有边界
返回值 返回一个 Series 数组

在这里插入图片描述
查看分组数量情况

Series数组.value_counts()

用于查看分组数量情况

例:
在这里插入图片描述

(2)将分组结果转换为 one-hot 编码

pd.get_dummies(sr, prefix=)

将分组结果转换为 one-hot 编码
sr 经过分组操作的 Series 数组
prefix 指定前缀,一般取属性名即可

例:就以身高分组为例

数据
height = [165, 174, 160, 180, 159, 163, 192, 184]

离散化结果
在这里插入图片描述
分组
在这里插入图片描述
将分组结果转换为 one-hot 编码
在这里插入图片描述


四、合并处理
1.按方向拼接

pd.concat([ ], axis=0)

按照行或列进行拼接
[ ] 要进行拼接的数组,列表形式

  • axis 指定按行或按列进行拼接:
    axis=0 表示进行竖直拼接
    axis=1或-1 表示进行水平拼接

:如果存在数据空缺的情况,空缺的位置用缺失值 NaN 填充

例:根据身高表,对身高进行数据离散化,再利用拼接将离散化后的数据拼接回原身高表中

数据
在这里插入图片描述
准备数据

import numpy as np
import pandas as pd

index = ["张三", "李四", "王二", "小蕾", "小明", "老王", "王五", "小六"]
columns = ["序号", "身高"]
information = np.array([[1, 165], [2, 174], [3, 160], [4, 180], [5, 159], [6, 163], [7, 192], [8, 184]])

information = pd.DataFrame(information, index=index, columns=columns)

在这里插入图片描述
取出数据

height = pd.Series(information["身高"])

在这里插入图片描述
分组

height = pd.cut(height, [150, 165, 180, 195])

在这里插入图片描述
转换为 one-hot 编码

height = pd.get_dummies(height, prefix="身高")

拼接到原数据表上

information = pd.concat([information, height], axis=1)

在这里插入图片描述

2.按索引拼接

可以参考 SQL 中根据索引来进行连接的方式,一般可以根据主码来进行连接

pd.merge(left, right, how=“inner”, on=[ ])

left 左表
right 右表
how=“inner” 连接方式,默认连接方式为内连接
on=[ ] 索引,即按什么索引进行连接,一般可以是主码主码组

how 参数含义
“left”左外连接
“right”右外连接
“outer”外连接
“inner”内连接

在有意义的一张表中,索引就是这张表的属性,而每一行就是一个个不同的事物

当两张表进行连接时,会根据 on 所指定的索引中值相等的行 (因为 on 指定的索引/属性中,值相等的行可以视为同一事物。这些行在左表中具有一些属性;在右表中具有其他属性,这些所有属性组合起来,构成了新的表中的这些行的所有属性) 构成新的表。而那些 on 所指定的索引在两张表之间没有相同值的行,在构成新的表时由于缺少了某一张表的属性,而导致在构成新的表时缺少完整的属性,而只能用 NaN 来表示
在这里插入图片描述
在新的表中,对这些含 NaN 的行的不同的保留情况,分为了四种不同的连接方式:

  • 内连接:不保留那些 on 所指定的索引在两张表之间没有相同值的行,即不保留含 NaN 的行
  • 外连接:保留那些 on 所指定的索引在两张表之间没有相同值的行,即保留含 NaN 的行
  • 左外连接:保留出现在左表中那些 on 所指定的索引在两张表之间没有相同值的行,即保留左表那些含 NaN 的行
  • 右外连接:保留出现在右表中那些 on 所指定的索引在两张表之间没有相同值的行,即保留右表那些含 NaN 的行

:大多数情况下使用的是内连接

例:

数据

left = pd.DataFrame({"key1": ["K0", "K0", "K1", "K2"], 
					 "key2": ["K0", "K1", "K0", "K1"], 
					 "A": ["A0", "A1", "A2", "A3"], 
					 "B": ["B0", "B1", "B2", "B3"]})

right = pd.DataFrame({"key1": ["K0", "K1", "K1", "K2"], 
					 "key2": ["K0", "K0", "K0", "K0"], 
					 "C": ["C0", "C1", "C2", "C3"], 
					 "D": ["D0", "D1", "D2", "D3"]})

在这里插入图片描述
内连接
在这里插入图片描述
外连接
在这里插入图片描述
左外连接
在这里插入图片描述
右外连接
在这里插入图片描述

五、交叉表与透视表

交叉表透视表可以理解成将两个变量放在一起,探索两个变量之间的关系

1.交叉表

pd.crosstab(value1, value2)

value1value2 两个数据列表比较
value1 数据列表1
value2 数据列表2


例:

准备数据:自 2020-01-01 开始,生成 600 天的股票涨跌数据

import numpy as np
import pandas as pd

stock_rate = np.random.normal(size=(600, 1))
date = pd.date_range(start = "2021-01-01", periods=600, freq="D")
stock_rate = pd.DataFrame(stock_rate, index=date, columns=["涨跌幅"])


要求:统计星期和涨跌幅之间的关系

根据要求,增加一列星期索引/属性

date = pd.to_datetime(stock_rate.index)
stock_rate["星期"] = date.weekday

在这里插入图片描述
根据要求,增加一列涨跌情况属性(1表示涨,0表示跌)

stock_rate["涨跌情况"] = np.where(stock_rate["涨跌幅"] > 0, 1, 0)

在这里插入图片描述
生成交叉表

data = pd.crosstab(stock_rate["星期"], stock_rate["涨跌情况"])

在这里插入图片描述

  • 这里统计了所有股票中不同星期中的涨跌情况

将交叉表的数值显示转化为频率显示

data.div(data.sum(axis=1), axis=0)

首先分别计算每个星期股票的总数:
data.sum(axis=1)

然后再让每个星期中的涨跌数量情况除以总数,即可转化为涨跌的频率:
data.div(data.sum(axis=1), axis=0)

注意:由于 data.sum(axis=1) 是一维数组,而 data 是二维数组;我们需要 data 除以竖直的 data.sum(axis=1),因此我们在 div(other[, axis=1]) 中,需要把 other 行列转置一下,即指定 axis=0 即可
一维数组:在这里插入图片描述 二维数组:在这里插入图片描述
在这里插入图片描述
最后我们画成柱状图的形式来进行表示

data.div(data.sum(axis=1), axis=0).plot(kind="bar", stacked=True)

:这里的 stacked=True 就是把柱状图设置为堆叠显示
在这里插入图片描述
如果出现红色报错,可能存在中文显示错误,加上以下代码即可

import matplotlib.pyplot as plt
# 指定默认字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.family']='sans-serif'
# 解决负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False

2.透视表

DataFrame数组.pivot_table([ ], index=[ ])

使用透视表,实现刚才的过程更加简单
DataFrame数组 需要进行操作的总表
[ ] 需要进行分组的内容——因变量
index=[ ] 按照 index=[ ] 索引进行分组——自变量

例:
在这里插入图片描述
这里直接显示的就是 1 的占比

六、分组与聚合

分组与聚合的含义,如图

如:表格中的 name 的分数 score 是累加的,且表格中的累加过程并不删除,而是保留在表格中,那么这种情况下,就需要对最终分数 score 进行筛选:

如图,先根据主码 name 进行分组,分组后取最大值后即为聚合
在这里插入图片描述

object_ = DataFrame.groupby(by=索引, as_index=False)

根据 by=索引 对数组进行分组
by=索引 是分组的依据,会根据指定索引把值相同的行分为一组

例:

数据

col = pd.DataFrame({"color": ["white", "red", "green", "red", "green"], 
                    "object": ["pen", "pencil", "pencil", "ashtray", "pen"], 
                    "price1": [5.56, 4.20, 1.30, 0.56, 2.75], 
                    "price2": [4.75, 4.12, 1.60, 0.75, 3.15]})

在这里插入图片描述
分组并聚合

col.groupby(by="color")["price1"].max()

在这里插入图片描述

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值