Pandas数据清洗
admin
2024-01-28 02:21:11
0

深入浅出Pandas读书笔记

C10 Pandas数据清洗

10.1 缺失值的认定

10.1.1 缺失值类型

一般使用NaN代表缺失值, 可以使用Numpy定义为np.nan或np.NaN. 在Pandas 1.0以后的版本中, 实验性的使用标量pd.NA来代表

df = pd.DataFrame({'A': ['a1', 'a1', 'a2', 'a2'],'B': ['b1', 'b2', None, 'b2'],'C': [1, 2, 3, 4],'D': [5, 6, None, 8],'E': [5, None, 7, 8]
})
# 可以将无穷值设置为缺失值
pd.options.mode.use_inf_as_na = True

10.1.2 缺失值判断

df.isna()及其别名df.isnull(), df.notna()

df.isna()
df.D.isna()
df.notna()
df.D.notna()

10.1.3 缺失值统计

利用sum, 将False当做0, 将True当做1

pd.Series([True, True, False]).sum()
# 每列有多少个缺失值
df.isnull().sum() # 每行 df.isnull().sum(1)
# 总共多少个缺失值
df.isnull().sum().sum()

10.1.4 缺失值筛选

# 筛选有缺失值的行
df[df.isnull().any(1)]
# 有缺失值的列
df.loc[:, df.isnull().any(0)]

10.1.5 NA标量

pd.NA 它代表空整数, 空布尔, 空字符. pd.NA的目标是提供一个缺失值的指示器, 该提示器可以在各种数中一致使用(而不是np.nan, None, 或者pd.NaT, 具体取决于数据类型)

s = pd.Series([1, 2, None, 4], dtype='Int64')
s[2] is pd.NA # True

10.1.6 时间数据中的缺失值

Pandas提供了一个NaT来表示, 并且NaT和NaN是兼容的

# None 根据整体的数据类型, 自动推断为NaT
pd.Series([pd.Timestamp('20200101'), None, pd.Timestamp('20200103')])

10.1.7 整型数据中的缺失值

pd.Series([1, 2, np.nan, 4], dtype='Int64') 

10.1.8 插入缺失值

10.2 缺失值的操作

10.2.1 缺失值的填充 df.fillna()

df.fillna(0)
df.fillna('missing')
df.one.fillna('暂无')
df.fillna(0, limit=1) # 只替换1个
# 将不同列的缺失值替换为不同的值
values = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
df.fillna(value=values)
  • pad / ffill 向前填充, 使用前一个有效值填充, df.fillna(method=‘ffill’)可以简写为df.ffill()
  • bfill / backfill 向后填充, 使用后一个有效值填充, df.fillna(method=‘fill’)可以简写为df.bfill()
df.fillna(method='bfill')
df.fillna(method='ffill')
# 填充列的平均值
df.fillna(df.mean())
# 将指定列的空值替换为指定值
df.replace({'toy': {np.nan: 100}})

10.2.2 插值填充 interpolate线性插值

插值interpolate是离散函数拟合的重要方法, 利用它可以根据函数在有限个点处的取值状况, 估算出函数在其他点处的近似值. Series和DataFrame对象都有interpolate()方法, 默认情况下, 该方法在缺失值处执行线性插值.它利用数学方法来估计缺失值, 对于较大的数据非常有用.

s = pd.Series([0, 1, np.nan, 3])
s.interpolate()
'''
0    0.0
1    1.0
2    2.0
3    3.0
dtype: float64
'''

10.2.3 缺失值删除 df.dropna()

df # 原数据
'''A	B	C	D	E
0	a1	b1	1	5.0	5.0
1	a1	b2	2	6.0	NaN
2	a2	None	3	NaN	7.0
3	a2	b2	4	8.0	8.0
'''
# 删除有缺失值的行
df.dropna()
'''A	B	C	D	E
0	a1	b1	1	5.0	5.0
3	a2	b2	4	8.0	8.0
'''
# 删除有缺失值的列
df.dropna(axis=1)
'''A	C
0	a1	1
1	a1	2
2	a2	3
3	a2	4
'''
# 删除所有值都缺失的行
df.dropna(how='all')
# 删除至少有2个缺失值的行
df.dropna(thresh=2)
# 指定判断缺失值的列范围
df.dropna(subset=['name', 'born'])
# 指定列的缺失值删除
df.col.dropna()

10.2.4 缺失值参与计算

加法会忽略缺失值, 或者将其按0处理
cumsum()和cumprod()会忽略NA值, 但值会保留在序列中, 可以使用skipna=False跳过有缺失值的计算并返回缺失值
df.count()在统计时, 缺失值不计数
缺失值在做聚合分组操作时, 如果聚合分组的列里有空值, 则会自动忽略这些值. 如果需要计入有空值的分组, 使用dropna=False

10.3 数据替换 replace

10.3.1 指定值替换

s = pd.Series([0, 1, 2, 3, 4,])
s.replace(0, 5)
# 一一对应进行替换
s.replace([0, 1, 2, 3, 4], [4, 3, 2, 1, 0])
# 用字典映射对应替换值
s.replace({0: 10, 1: 100})
# 将a的0, b的5替换为100
df.replace({'a': 0, 'b': 5}, 100)
# 指定a里面的替换规则
df.replace({'a': {0: 100, 4: 400}})

10.3.2 使用替换方式

# 将1, 2, 3替换为他们前一个值
s.replace([1, 2, 3], method='ffill')
s.replace([1, 2, 3], method='bfill') # 替换为后一个值

如果指定的要替换的值不存在, 则不起作用, 也不会报错, 以上的替换也适用于字符类型数据

10.3.3 字符替换 df.replace()正则

# 利用正则表达式将ba开头的值替换为new
df.replace(to_replace=r'^ba.$', value='new', regex=True)
# 如果多列规则不一, 可以按以下格式对应传入
df.replace({'A': r'1$', 'B': r'2$'}, {'A': 'new', 'B': 'new2'}, regex=True)
# 多个规则均替换为同样的值
df.replace(regex=[r'^ba.$', 'foo'], value='new')
# 多个规则及对应的替换内容
df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})

10.3.4 缺失值替换

列如我们可以先将无效的值替换为nan, 再进行缺失值处理

d = {'a': list(range(4)), 'b': list('ab..'),'c': ['a', 'b', np.nan, 'd']}
df = pd.DataFrame(d)
# 将.替换为NaN
df.replace('.', np.nan)
# 对应替换, a换b, 点换NaN
df.replace(['a', '.'], ['b', np.nan])
# a后面加上stuff
df.replace([r'\.', r'(a)'], ['dot', r'\1stuff'], regex=True)
# b中的点替换为np.nan
df.replace({'b': '.'}, {'b': np.nan})
# b列的b替换为空
df.replace({'b': {'b': ''}})

10.3.5 数字替换

# 生成数据
df = pd.DataFrame(np.random.rand(10, 2))
df[np.random.rand(df.shape[0]) > 0.5] = 1.5 # 将某些数字改成1.5
df.replace(1.5, np.nan) # 将1.5 修改为np.nan
df.replace([1.5, df.iloc[0, 0]], [np.nan, 'a']) # 将1.5改成NaN, 将左上角改成'a'

10.3.6 数据修剪

对于数据中存在的极端值, 过大或者过小, 可以使用df.clip(lower, upper)来修剪, 当数据大于upper时使用upper的值, 小于lower使用lower的值, 与numpy.clip方法一样

df = pd.DataFrame({'a': [-1, 2, 5], 'b': [6, 1, -3]})
df.clip(0, 3)

10.4 重复值及删除数据

10.4.1 重复值识别 df.duplicated()

df.duplicated(subset=None, keep='first')

它可以返回表示重复行的布尔值序列, 默认为一行的所有内容, subset可以指定列, keep参数用来确定要标记的重复值

  • first
  • last
  • False
df = pd.DataFrame({'A': ['x', 'x', 'z'], 'B': ['x', 'x', 'x'], 'C': [1, 1, 2]})
df
'''A	B	C
0	x	x	1
1	x	x	1
2	z	x	2
'''
# 全行检测, 除第一次出现的外, 重复的为True
df.duplicated()
'''
0    False
1     True
2    False
dtype: bool
'''
# 除最后一次出现的外, 重复的True
df.duplicated(keep='last')
'''
0     True
1    False
2    False
dtype: bool
'''
# 所有重复的都为True
df.duplicated(keep=False)
'''
0     True
1     True
2    False
dtype: bool
'''
# 指定列检测
df.duplicated(subset=['B'], keep=False)
'''
0    True
1    True
2    True
dtype: bool
'''

10.4.2 删除重复值 df.drop_duplicates()

df.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)

参数说明

  • subset 指定的标签或标签序列, 仅删除这些列重复值, 默认情况为所有列
  • keep
    • first 保留一地刺出现的重复值
    • last 最后
    • False 删除所有重复值
  • inplace
  • ignore_index 处理后, 重新分配自然索引

10.4.3 删除数据 df.drop()

df.drop()通过指定标签名称和相应的轴, 或直接给定索引或列名称来删除行或列, 使用多层索引时, 可以通过指定级别来删除不同级别上的标签

df.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')

参数说明

  • labels 要删除的列或者行, 如果要删除多个, 传入列表
  • axis
  • index
  • column
  • level 索引层级, 将删除此层级
  • inplace
  • errors ignore或者raise, 默认raise, 如果为ignore, 则容忍错误, 仅删除现有标签
df.drop([0, 1])
'''
A	B	C
2	z	x	2
'''
df.drop(['B', 'C'], axis=1)
df.drop(columns=['B', 'C']) # 同上

10.5 NumPy格式转换

10.5.1 转换方法

  • ds.to_numpy() 可以用在Index, Series和DataFrame对象
  • s.array 为PandasArray, 用在Index和Series
    不在推荐使用pandas的values和as_matrix()

10.5.2 DataFrame转为ndarray

df.values和df.to_numpy()返回的是一个array类型

df.values # 不推荐
df.to_numpy() # 结果同上
type(df.to_numpy()) # numpy.ndarray
# 转换指定的列
df[['name', 'Q1']].to_numpy()

10.5.3 Series转为ndarray

s.values和s.to_numpy()返回的是一个array类型

10.5.4 df.to_records()

10.5.5 np.array

可以用np.array直接读取DataFrame或者Series数据, 最终也会转换为array类型

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...