数据清洗
数据清洗是对一些没有用的数据进行处理的过程。
很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况,如果要使数据分析更加准确,就需要对这些没有用的数据进行处理。
数据清洗与预处理的常见步骤:
-
缺失值处理:识别并填补缺失值,或删除含缺失值的行/列。
-
重复数据处理:检查并删除重复数据,确保每条数据唯一。
-
异常值处理:识别并处理异常值,如极端值、错误值。
-
数据格式转换:转换数据类型或进行单位转换,如日期格式转换。
-
标准化与归一化:对数值型数据进行标准化(如 Z-score)或归一化(如 Min-Max)。
-
类别数据编码:将类别变量转换为数值形式,常见方法包括 One-Hot 编码和标签编码。
-
文本处理:对文本数据进行清洗,如去除停用词、词干化、分词等。
-
数据抽样:从数据集中抽取样本,或通过过采样/欠采样处理类别不平衡。
-
特征工程:创建新特征、删除不相关特征、选择重要特征等。
常用方法及说明
数据清洗与预处理的常见方法:
操作 | 方法/步骤 | 说明 | 常用函数/方法 |
---|---|---|---|
缺失值处理 | 填充缺失值 | 使用指定的值(如均值、中位数、众数等)填充缺失值。 | df.fillna(value) |
删除缺失值 | 删除包含缺失值的行或列。 | df.dropna() | |
重复数据处理 | 删除重复数据 | 删除 DataFrame 中的重复行。 | df.drop_duplicates() |
异常值处理 | 异常值检测(基于统计方法) | 通过 Z-score 或 IQR 方法识别并处理异常值。 | 自定义函数(如基于 Z-score 或 IQR) |
替换异常值 | 使用合适的值(如均值或中位数)替换异常值。 | 自定义函数(如替换异常值) | |
数据格式转换 | 转换数据类型 | 将数据类型从一个类型转换为另一个类型,如将字符串转换为日期。 | df.astype() |
日期时间格式转换 | 转换字符串或数字为日期时间类型。 | pd.to_datetime() | |
标准化与归一化 | 标准化 | 将数据转换为均值为0,标准差为1的分布。 | StandardScaler() |
归一化 | 将数据缩放到指定的范围(如 [0, 1])。 | MinMaxScaler() | |
类别数据编码 | 标签编码 | 将类别变量转换为整数形式。 | LabelEncoder() |
独热编码(One-Hot Encoding) | 将每个类别转换为一个新的二进制特征。 | pd.get_dummies() | |
文本数据处理 | 去除停用词 | 从文本中去除无关紧要的词,如 "the" 、 "is" 等。 | 自定义函数(基于 nltk 或 spaCy ) |
词干化与词形还原 | 提取词干或恢复单词的基本形式。 | nltk.stem.PorterStemmer() | |
分词 | 将文本分割成单词或子词。 | nltk.word_tokenize() | |
数据抽样 | 随机抽样 | 从数据中随机抽取一定比例的样本。 | df.sample() |
上采样与下采样 | 通过过采样(复制少数类样本)或欠采样(减少多数类样本)来平衡数据集中的类别分布。 | SMOTE() (上采样); RandomUnderSampler() (下采样) | |
特征工程 | 特征选择 | 选择对目标变量有影响的特征,去除冗余或无关特征。 | SelectKBest() |
特征提取 | 从原始数据中创建新的特征,提升模型的预测能力。 | PolynomialFeatures() | |
特征缩放 | 对数值特征进行缩放,使其具有相同的量级。 | MinMaxScaler() 、 StandardScaler() | |
类别特征映射 | 特征映射 | 将类别变量映射为对应的数字编码。 | 自定义映射函数 |
数据合并与连接 | 合并数据 | 将多个 DataFrame 按照某些列合并在一起,支持内连接、外连接、左连接、右连接等。 | pd.merge() |
连接数据 | 将多个 DataFrame 进行行或列拼接。 | pd.concat() | |
数据重塑 | 数据透视表 | 将数据根据某些维度进行分组并计算聚合结果。 | pd.pivot_table() |
数据变形 | 改变数据的形状,如从长格式转为宽格式或从宽格式转为长格式。 | df.melt() 、 df.pivot() | |
数据类型转换与处理 | 字符串处理 | 对字符串数据进行处理,如去除空格、转换大小写等。 | str.replace() 、 str.upper() 等 |
分组计算 | 按照某个特征分组后进行聚合计算。 | df.groupby() | |
缺失值预测填充 | 使用模型预测填充缺失值 | 使用机器学习模型(如回归模型)预测缺失值,并填充缺失数据。 | 自定义模型(如 sklearn.linear_model.LinearRegression ) |
时间序列处理 | 时间序列缺失值填充 | 使用时间序列的方法(如前向填充、后向填充)填充缺失值。 | df.fillna(method='ffill') |
滚动窗口计算 | 使用滑动窗口进行时间序列数据的统计计算(如均值、标准差等)。 | df.rolling(window=5).mean() | |
数据转换与映射 | 数据映射与替换 | 将数据中的某些值替换为其他值。 | df.replace() |
1 清洗空值
1 删除包含空值的行或列-dropna()
如果我们要删除包含空字段的行,可以使用 dropna() 方法,语法格式如下:
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
参数说明:
- axis:默认为 0,表示逢空值剔除整行,如果设置参数 axis=1 表示逢空值去掉整列。
- how:默认为 'any' 如果一行(或一列)里任何一个数据有出现 NA 就去掉整行,如果设置 how='all' 一行(或列)都是 NA 才去掉这整行。
- thresh:设置需要多少非空值的数据才可以保留下来的。
- subset:设置想要检查的列。如果是多个列,可以使用列名的 list 作为参数。
- inplace:如果设置 True,将计算得到的值直接覆盖之前的值并返回 None,修改的是源数据。
fillna() 方法来替换一些空字段
2 替换空值-fillna
基本语法
fillna(value=None, method=None, axis=None, inplace=False,
limit=None, downcast=None, **kwargs)
参数说明
- value:固定值,可以用固定数字、均值、中位数、众数等,此外还可以用字典,series等形式数据;
- method:填充方法,'bfill','backfill','pad','ffill'
- axis: 填充方向,默认0和index,还可以填1和columns
- inplace:在原有数据上直接修改
- limit:填充个数,如1,每列只填充1个缺失值
示例:
示例1 value=X:固定值填充
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,21,np.nan,16],
'Class':['two','one',np.nan,'three']})
print('df:\n', df)
print("# 用数字0填充空值 不修改原对象inplace=False #")
print(df.fillna(value=0,inplace=False))
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang NaN NaN
3 Li Li 16.0 three
# 用数字0填充空值 不修改原对象inplace=False #
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang 0.0 0
3 Li Li 16.0 three
'''
示例2 使用均值填充-mean
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,21,np.nan,16],
'Class':['two','one',np.nan,'three']})
print('df:\n', df)
print("# 使用列Age的均值对NA进行填充 #")
print(df.fillna(df['Age'].mean()))
# 使用列Age的均值对Age列的NA进行填充
print("mean() 填充")
print(df['Age'].fillna(df['Age'].mean()))
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang NaN NaN
3 Li Li 16.0 three
# 使用列Age的均值对NA进行填充 #
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang 19.0 19.0
3 Li Li 16.0 three
mean() 填充
0 20.0
1 21.0
2 19.0
3 16.0
Name: Age, dtype: float64
'''
示例3 中位数填充-median
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,21,np.nan,16],
'Class':['two','one',np.nan,'three']})
print('df:\n', df)
# 中位数填充
print("median() 填充")
print(df['Age'].fillna(df['Age'].median()))
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang NaN NaN
3 Li Li 16.0 three
median() 填充
0 20.0
1 21.0
2 20.0
3 16.0
Name: Age, dtype: float64
'''
3 使用每列缺失值前面的值进行填充-ffill
基本语法
DataFrame.ffill(axis=None, inplace=False, limit=None, downcast=None)
参数说明
- axis:填充的方向。{0 or ‘index’, 1 or ‘columns’},默认为0。
- inplace:是否在原对象上进行修改,默认为False。
- limit:指定连续填充的最大数量,默认为None。
- downcast:可选,将结果转换为指定的dtype,默认为None
示例
示例1 按行使用缺失值前面的值进行填充-axis = 0(默认)
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,21,np.nan,16],
'Class':['two','one',np.nan,'three']})
print('df:\n', df)
print("按行使用缺失值前面的值进行填充")
print(df.ffill())
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang NaN NaN
3 Li Li 16.0 three
按行使用缺失值前面的值进行填充
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang 21.0 one
3 Li Li 16.0 three
'''
示例2 按列使用缺失值前面的值进行填充-axis=1
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,21,np.nan,16],
'Class':['two','one',np.nan,'three']})
print('df:\n', df)
print("按列使用缺失值前面的值进行填充")
print(df.ffill(axis = 1))
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang NaN NaN
3 Li Li 16.0 three
按列使用缺失值前面的值进行填充
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang Wu Wang Wu Wang
3 Li Li 16.0 three
'''
4 使用缺失值后面的值进行填充-bfill
基本语法:
DataFrame.ffill(axis=None, inplace=False, limit=None, downcast=None)
参数说明:
- axis:填充的方向。{0 or ‘index’, 1 or ‘columns’},默认为0。
- inplace:是否在原对象上进行修改,默认为False。
- limit:指定连续填充的最大数量,默认为None。
- downcast:可选,将结果转换为指定的dtype,默认为None
示例:
示例1 按行使用缺失值后面的值进行填充-axis= 0(默认)
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,21,np.nan,16],
'Class':['two','one',np.nan,'three']})
print('df:\n', df)
print("使用每行缺失值后面的值进行填充")
print(df.bfill())
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang NaN NaN
3 Li Li 16.0 three
bfill 使用每行缺失值后面的值进行填充
Name Age Class
0 San Zhang 20.0 two
1 Si Li 21.0 one
2 Wu Wang 16.0 three
3 Li Li 16.0 three
'''
示例2 按列使用缺失值后面的值进行填充-axis=1
import pandas as pd
import numpy as np
df = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang ','Li Li'],
'Age':[20,np.nan,21,16],
'Class':['two','one',np.nan,'three']})
print("df:\n",df)
print("axis = 1 使用每列缺失值后面的值进行填充")
print(df.bfill( axis = 1))
'''
输出结果:
df:
Name Age Class
0 San Zhang 20.0 two
1 Si Li NaN one
2 Wu Wang 21.0 NaN
3 Li Li 16.0 three
axis = 1 使用每列缺失值后面的值进行填充
Name Age Class
0 San Zhang 20.0 two
1 Si Li one one
2 Wu Wang 21.0 NaN
3 Li Li 16.0 three
'''
2 清洗重复数据
如果我们要清洗重复数据,可以使用 duplicated() 和 drop_duplicates() 方法。
如果对应的数据是重复的,duplicated() 会返回 True,否则返回 False。
duplicated使用例子:
import pandas as pd
person = {
"name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
"age": [50, 40, 40, 23]
}
df = pd.DataFrame(person)
print(df.duplicated())
'''
以上实例输出结果如下:
0 False
1 False
2 True
3 False
dtype: bool
'''
删除重复数据-drop_duplicates()
import pandas as pd
persons = {
"name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
"age": [50, 40, 40, 23]
}
df = pd.DataFrame(persons)
df.drop_duplicates(inplace = True)
print(df)
'''
以上实例输出结果如下:
name age
0 Google 50
1 Runoob 40
3 Taobao 23
'''
3 清洗格式错误数据
数据格式错误的单元格会使数据分析变得困难,甚至不可能。
我们可以通过包含空单元格的行,或者将列中的所有单元格转换为相同格式的数据。
格式化日期实例:
import pandas as pd
# 第三个日期格式错误
data = {
"Date": ['2020/12/01', '2020/12/02' , '20201226'],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
df['Date'] = pd.to_datetime(df['Date'], format='mixed')
print(df.to_string())
'''
以上实例输出结果如下:
Date duration
day1 2020-12-01 50
day2 2020-12-02 40
day3 2020-12-26 45
'''
4 清洗错误数据
数据错误也是很常见的情况,我们可以对错误的数据进行替换或移除。
例子:替换错误年龄的数据:
import pandas as pd
person = {
"name": ['Google', 'Runoob' , 'Taobao'],
"age": [50, 40, 12345] # 12345 年龄数据是错误的
}
df = pd.DataFrame(person)
df.loc[2, 'age'] = 30 # 修改数据
print(df.to_string())
以上实例输出结果如下:
name age
0 Google 50
1 Runoob 40
2 Taobao 30
例子-将 age 大于 120 的设置为 120:
import pandas as pd
person = {
"name": ['Google', 'Runoob' , 'Taobao'],
"age": [50, 200, 12345]
}
df = pd.DataFrame(person)
for x in df.index:
if df.loc[x, "age"] > 120:
df.loc[x, "age"] = 120
print(df.to_string())
以上实例输出结果如下:
name age
0 Google 50
1 Runoob 120
2 Taobao 120
例子-将 age 大于 120 的删除::
import pandas as pd
person = {
"name": ['Google', 'Runoob' , 'Taobao'],
"age": [50, 40, 12345] # 12345 年龄数据是错误的
}
df = pd.DataFrame(person)
for x in df.index:
if df.loc[x, "age"] > 120:
df.drop(x, inplace = True)
print(df.to_string())
'''
以上实例输出结果如下:
name age
0 Google 50
1 Runoob 40
'''