数据清洗:生成模拟数据,处理缺失值、异常值、重复值(含python代码)数据建模拿到数据后第一步。

一:简介:

        在进行数值模拟或者建立数据模型前,需要将实验数据进行数据清洗和预处理。本文主要介绍数据清洗的常见步骤和技巧。

二:生成模拟数据

        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,公式为:

                                                  Z = \left ( x-\mu \right )/\sigma

        其中,𝑋 是数据点的值,𝜇 是数据集的均值,σ 是数据集的标准差。

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,公式为:IQR = Q3-Q1

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)、决策树等,来减少异常值对模型的影响。

        选择哪种方法取决于数据的特点、异常值的分布情况以及具体的分析目的。在处理异常值时,需要根据实际情况选择合适的方法,并且要注意处理异常值可能会对数据造成的影响。

五:重复值处理

        

  1. 识别重复值

    • 首先,需要识别数据集中是否存在重复值。可以使用duplicated()函数来检测重复行,
  2. 删除重复值

    • 最简单的方法是直接删除重复值。
      可以使用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

  • 28
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值