一:简介:
在进行数值模拟或者建立数据模型前,需要将实验数据进行数据清洗和预处理。本文主要介绍数据清洗的常见步骤和技巧。
二:生成模拟数据
1、生成线性数据
ndarray = numpy.linspace(start, stop, num, endpoint, retstep, dtype=None)
ndarray = numpy.arange(start, end, step)
list = range(start, end, step)
import numpy as np
#numpy库中的linspace()方法-------
#一个是产生线性数据的方法,参数(起始值,末端值,一共插入多少个数,endpoint="True"是否包含末端
#值,retstep="True"是否包含步长,dtype=‘int’:数据类型)
data1 = np.linspace(0,100,101,endpoint="True")
print(type(data1))
#res: <class 'numpy.ndarray'>
#numpy.arange()函数-----------
# arange(start, end, step),以start开始,以stop终止,不包含末尾值,步长为step,默认步长为1。
# 可以使用float型数据。当未指定start及stop时,以固定步长1生成以0开头的若干个数字。
x=np.arange(1,10,2)
# array([1, 3, 5, 7, 9])
x=np.arange(1,10)
# array([1, 2, 3, 4, 5, 6, 7, 8, 9])
x=np.arange(5)
# array([0, 1, 2, 3, 4])
x=np.arange(1.2,3)
# array([1.2, 2.2])
x=np.arange(1.2,3,0.5)
# array([1.2, 1.7, 2.2, 2.7])
#range()函数----------------
#range(start, end, step),返回一个list对象,起始值为start,终止值为end,但不含终止值,步长为#step。只能创建int型list。
x=list(range(1,10))
#[1, 2, 3, 4, 5, 6, 7, 8, 9]
x=list(range(1,10,2))
#[1, 3, 5, 7, 9]
x=list(range(1.0,10,2)) #不支持float类型
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-51-e5e38bc19724> in <module>
----> 1 x=list(range(1.0,10,2))
2 x
TypeError: 'float' object cannot be interpreted as an integer
2、随机生成数据:
1)random 模块中的随机数
import random
#生成随机数据------------------------------
# 1、random.random() 函数:这会生成一个 0 到 1 之间的随机浮点数。
# 每次调用 random() 函数都会得到一个不同的随机数。
num1 = random.random()
# 2、random.randint() 函数:这会生成一个指定范围内的随机整数(
# 在这个例子中是 1 到 10 之间的整数)。边界值都是包含在内的。
num2 = random.randint(1,10)
# 3、random.choice() 函数:这会从列表中随机选择一个元素。
items = [1, 2, 3, 4, 5]
num3 = random.choice(items)
# 4、random.huffle() 函数:这会将列表中的元素随机打乱顺序。
items = [1, 2, 3, 4, 5]
random.shuffle(items)
# 5、random.seed() 函数:seed() 函数用于初始化随机数生成器。
# 如果使用相同的种子,每次生成的随机数序列都是相同的
random.seed(10)
num = random.random()
2)numpy库中的随机数 numpy.random
#numpy.random.rand():生成一个给定形状的数组,数组中的元素是在 [0, 1) 范围内
#均匀分布的随机数。在这个例子中,生成一个 3x2 的数组。
arr = np.random.rand(3, 2)
# numpy.random.randn():生成一个给定形状的数组,数组中的元素是从
# 标准正态分布(均值为 0,标准差为 1)中随机采样得到的。
# 在这个例子中,生成一个 3x2 的数组。
arr = np.random.randn(3, 2)
# numpy.random.randint():生成一个给定形状的数组,数组中的元素是
# 在指定的范围内(包含边界)随机选择的整数。在这个例子中,生成一个 3x2 的数组,
# 元素范围在 1 到 10 之间。
arr = np.random.randint(1, 10, size=(3, 2))
# numpy.random.random_sample():生成一个给定形状的数组,数组中的元素是在 [0, 1)
# 范围内均匀分布的随机数。在这个例子中,生成一个 3x2 的数组。
arr = np.random.random_sample((3, 2))
# numpy.random.choice():从给定的一维数组或列表中随机选择元素来填充给定形状的数组。
# 在这个例子中,从 [1, 2, 3, 4, 5] 中随机选择元素来生成一个 3x2 的数组。
arr = np.random.choice([1, 2, 3, 4, 5], size=(3, 2))
三:缺失值处理
1、判断缺失值 pandas.isnull(data)
#判断是否为空值,返回的是boolean类型DataFrame。
#手动在d1中添加一个None
data1 = np.linspace(0,100,11,endpoint="True")
d2 = np.append(data1,None)
#两个方法都可以判断
# print(pandas.isnull(d2))
print(pandas.isna(d2))
#res: [False False False False False False False False False False False True]
2、删除缺失值
df.dropna(axis=1, how='all',thresh:5):
axis:默认不填写为0。删除包含缺失值所在的行;为1时,删除包含缺失值的列。
how:默认为any.只要有缺失值就删除行/列;为all时,整行/列都为缺失值时才删除该行/列。
thresh:非空元素最低数量。int型,默认为None。如果该行/列中,非空元素数量小于这个值,就删除该行/列。
inplace:是否原地替换。布尔值,默认为False。即不修改原来数据集,生成替换后新数据集的返回。如果为True,则在原DataFrame上进行操作,返回值为None。
import pandas as pd
# 创建一个包含缺失值的示例数据集
data = {'A': [1, 2, None, 4],
'B': [None, 5, 6, 7],
'C': [8, 9, 10, 11]}
df = pd.DataFrame(data)
# 删除包含缺失值的行
cleaned_df = df.dropna()
# 删除包含缺失值的列
cleaned_df = df.dropna(axis=1)
# 删除所有值都是缺失值的行
cleaned_df = df.dropna(how='all')
# 删除所有值都是缺失值的列
cleaned_df = df.dropna(axis=1, how='all')
3、填充缺失值
函数形式:fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
参数:
value:用于填充的空值的值。
method: {'backfill', 'bfill', 'pad', 'ffill', None}, default None。定义了填充空值的方法, pad / ffill表示用前面行/列的值,填充当前行/列的空值, backfill / bfill表示用后面行/列的值,填充当前行/列的空值。还有均值、中位数、众数法填充、线性插值和多项式插值
axis:轴。0或'index',表示按行删除;1或'columns',表示按列删除。
inplace:是否原地替换。布尔值,默认为False。如果为True,则在原DataFrame上进行操作,返回值为None。
limit:int, default None。如果method被指定,对于连续的空值,这段连续区域,最多填充前 limit 个空值(如果存在多段连续区域,每段最多填充前 limit 个空值)。如果method未被指定, 在该axis下,最多填充前 limit 个空值(不论空值连续区间是否间断)
downcast:dict, default is None,字典中的项为,为类型向下转换规则。或者为字符串“infer”,此时会在合适的等价类型之间进行向下转换,比如float64 to int64 if possible。
import pandas as pd
# 创建一个包含缺失值的示例数据集
data = {'A': [1, 2, None, 4],
'B': [None, 5, 6, 7],
'C': [8, 9, 10, 11]}
df = pd.DataFrame(data)
# 使用指定值填充缺失值。可以不是数值
df['B'] = df['B'].fillna(0)
# 使用前一个有效值填充缺失值(向前填充)
df['B'] = df['B'].fillna(method='ffill')
# 使用后一个有效值填充缺失值(向后填充)
df['B'] = df['B'].fillna(method='bfill')
# 使用常数填充缺失值
df.fillna(0, inplace=True)
#特殊的插值方法(重点)---------------------------------------------
# 使用均值填充缺失值
mean_A = df['A'].mean()
df['A'] = df['A'].fillna(mean_A)
# 中位数填充
median_A = df['A'].median()
df['A'] = df['A'].fillna(median_A)
# 众数填充:(注意:众数填充时要通过索引0进行取值,因为一组数据的众数可能有多个,
索引为0的数据一定会存在)
mode_B = df['B'].mode()[0]
df['B'] = df['B'].fillna(mode_B)
# 线性插值。该方法的本质是使用各种数学(统计学)中的插值方法进行填充,
#其中包含最近邻插值法、阶梯插值、线性插值、B样条曲线插值等多种方法。
df['C'] = df['C'].interpolate(method='linear')
# 多项式插值:具体用法不详,官方文档暂时没有看到详细的描述
from scipy.interpolate import interp1d
x = [0, 1, 2, 3]
y = [8, 1, 10, 61]
f = interp1d(x, y, kind='quadratic')
df['C'] = f(df.index)
4、使用专门的模型填充缺失值
有时候可以使用机器学习模型来预测缺失值,比如使用回归模型或者随机森林来填充缺失值。(日后会更新相关专题)
5、使用专门的缺失值处理工具
一些专门的库和工具(比如 scikit-learn 和 fancyimpute)提供了一些高级的缺失值处理方法,比如 KNN 填充、矩阵分解填充等。基本原理与上述类似,只是封装了库,方便使用。日后会更新相关专题。
四:异常值处理
1、识别异常值
1)Z-Score(Z分数):Z分数衡量了一个数据点与均值的偏离程度,可以通过计算每个数据点的Z分数来识别异常值。一般来说,绝对值大于3的Z分数被认为是异常值。
对于数据集中的每个数据点,计算其Z-Score,公式为:
其中,𝑋 是数据点的值,𝜇 是数据集的均值,σ 是数据集的标准差。
python
import pandas as pd
from scipy.stats import zscore
# 创建一个包含异常值的示例数据集
data = {'A': [1, 2, 3, 4, 1000]}
df = pd.DataFrame(data)
# 计算Z-Score
df['Z_Score'] = zscore(df['A'])
# 识别异常值
threshold = 3
df['Is_Outlier'] = abs(df['Z_Score']) > threshold
print(df)
2)IQR(四分位数间距):通过计算数据的四分位数(Q1和Q3),然后计算IQR(Q3-Q1),异常值可以被定义为小于Q1-1.5IQR或大于Q3+1.5IQR的值
计算IQR,公式为:
python
import pandas as pd
# 创建一个包含异常值的示例数据集
data = {'A': [1, 2, 3, 4, 1000]}
df = pd.DataFrame(data)
# 计算Q1、Q3和IQR
Q1 = df['A'].quantile(0.25)
Q3 = df['A'].quantile(0.75)
IQR = Q3 - Q1
# 定义异常值范围
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 识别异常值
df['Is_Outlier'] = (df['A'] < lower_bound) | (df['A'] > upper_bound)
print(df)
2、删除异常值
最简单的方法是直接删除包含异常值的行或列。这种方法适用于异常值对整体数据影响较小的情况。
3、截尾处理
可以将异常值截断到一个合理的范围内,例如将所有大于或小于某个阈值的数值设为该阈值。
4、填充处理
对于一些特定的场景,可以使用合理的数值来填充异常值,例如使用中位数、均值或者通过插值方法进行填充。参考空值插入。
5、离群值转换
可以对异常值进行转换,使其变得更接近正常数据的分布。例如,对数转换、平方根转换等。
6、使用异常值检测算法
可以使用一些专门的异常值检测算法,如孤立森林(Isolation Forest)、LOF(局部异常因子)等,来识别和处理异常值。与插值类似,后期会补充
7、使用鲁棒模型
在建模过程中,可以使用一些对异常值更加鲁棒的模型,如支持向量机(SVM)、决策树等,来减少异常值对模型的影响。
选择哪种方法取决于数据的特点、异常值的分布情况以及具体的分析目的。在处理异常值时,需要根据实际情况选择合适的方法,并且要注意处理异常值可能会对数据造成的影响。
五:重复值处理
-
识别重复值:
- 首先,需要识别数据集中是否存在重复值。可以使用
duplicated()
函数来检测重复行,
- 首先,需要识别数据集中是否存在重复值。可以使用
-
删除重复值:
-
最简单的方法是直接删除重复值。
可以使用drop_duplicates()
函数来删除数据集中的重复行,保留唯一的记录。 -
基于部分列删除重复值
有时候只需要根据部分列来判断重复值。可以使用subset
参数指定部分列来删除重复值。 -
保留重复值中的第一个或最后一个:
在删除重复值时,可以选择保留重复值中的第一个出现的记录或最后一个出现的记录。 -
标记重复值
有时候不想删除重复值,而是希望标记这些重复值。可以使用duplicated()
函数标记重复值。
-
import pandas as pd
data = {'A': [3.0,5,3,5],
'B': [4.0, 5, 4,5],
'C': [3.0, 9, 3, None]}
df = pd.DataFrame(data)
#不加subset=["A","B"]只有当所有的列都相等时才会判断为true,
print(df.duplicated())
# 为df添加一列,可以标记是否重复了
df['is_duplicate'] = df.duplicated()
#只有所有列相等才会删除
df.drop_duplicates(inplace=True)
print(df)
#只要A,B列中的相等就会删除该行。keep确定保留项目
df.drop_duplicates(subset=["A","B"],inplace=True,keep="last")
# df.drop_duplicates(subset=["A","B"],inplace=True,keep="first")
print(df)
参考地址:https://blog.csdn.net/qq_17753903/article/details/89892631