目录
引言
数据预处理是数据分析过程中不可或缺的一环,它的目的是为了使原始数据更加规整、清晰,以便于后续的数据分析和建模工作。在Python数据分析中,数据预处理通常包括数据清洗、数据转换和数据特征工程等步骤。
一、数据预处理概述
数据预处理是数据分析流程中的第一步,也是至关重要的一步。它涉及对原始数据进行清洗、转换、集成和规约,以消除噪声、填补缺失值、纠正错误,并将数据转换成适合分析的形式。通过有效的数据预处理,我们可以提高数据分析的质量和效率,为后续的数据挖掘和机器学习模型训练打下坚实的基础。
二、Python数据预处理工具与环境
Python是数据预处理领域的佼佼者,它拥有强大的数据处理库,如Pandas、NumPy和SciPy等。这些库提供了丰富的函数和方法,使得数据预处理变得简单而高效。为了搭建Python数据分析环境,我们可以选择安装Anaconda这样的科学计算发行版,它集成了Python和许多常用的数据科学库。同时,Jupyter Notebook也是一个非常流行的工具,它允许我们以笔记本的形式编写和执行Python代码,并方便地展示分析结果。
三、数据清洗
数据清洗是数据预处理的核心任务之一,它涉及对原始数据进行一系列的处理,以确保数据的准确性和一致性。以下将详细介绍缺失值处理、异常值检测与处理、重复数据的识别与删除,并给出具体的代码示例。
1. 缺失值处理
缺失值处理包括识别缺失值、删除缺失值或填充缺失值。以下是一个使用Pandas库进行缺失值处理的代码示例:
import pandas as pd
import numpy as np
# 加载数据
data = pd.read_csv('data.csv')
# 识别缺失值
print(data.isnull().sum())
# 删除含有缺失值的行
data_dropna = data.dropna()
# 填充缺失值,例如使用均值填充
data_fillna = data.fillna(data.mean())
# 也可以使用特定的值填充,如0
data_fillna_zero = data.fillna(0)
# 或者使用前一个值填充
data_fillna_ffill = data.fillna(method='ffill')
# 查看处理后的数据
print(data_dropna.head())
print(data_fillna.head())
2. 异常值检测与处理
异常值检测是识别那些与大多数数据显著不同的值。处理异常值的方法包括删除、替换或保留。以下是一个简单的异常值处理代码示例:
# 假设'column_with_outliers'是需要检测异常值的列
# 使用简单的统计方法检测异常值,如IQR(四分位距)
Q1 = data['column_with_outliers'].quantile(0.25)
Q3 = data['column_with_outliers'].quantile(0.75)
IQR = Q3 - Q1
# 定义异常值的条件
is_outlier = (data['column_with_outliers'] < (Q1 - 1.5 * IQR)) | (data['column_with_outliers'] > (Q3 + 1.5 * IQR))
# 删除异常值
data_no_outliers = data[~is_outlier]
# 或者替换异常值
data['column_with_outliers'][is_outlier] = np.nan # 可以选择替换为NaN或其他合适的值
# 查看处理后的数据
print(data_no_outliers.head())
3. 重复数据的识别与删除
重复数据可能导致分析结果的偏差,因此需要识别并删除。以下是一个识别并删除重复数据的代码示例:
duplicates = data.duplicated()
: 这行代码使用pandas库中的duplicated
函数,检查DataFrame对象data
中是否存在重复的行。该函数返回一个布尔型的Series,其中每个元素对应于data
中的一行,如果该行是重复的则为True,否则为False。
data_no_duplicates = data[\simduplicates]
: 这行代码通过布尔索引筛选出不重复的行,即那些在duplicates
中值为False的行。\simduplicates
表示取反操作,因此它会选择那些不是重复的行。
data_unique = data.drop_duplicates()
: 这行代码直接使用pandas库中的drop_duplicates
方法删除所有重复的行,并返回一个新的DataFrame对象,其中只包含唯一的行。
print(data_no_duplicates.head())
: 最后,这行代码打印出经过去重处理后的数据的前几行,以便查看结果。
综上所述,这段代码展示了如何使用pandas库来识别和处理数据中的重复项。首先,它检查数据中是否存在重复的行,然后通过布尔索引或drop_duplicates
方法去除这些重复项,并最终打印出处理后的数据。
# 识别重复数据
duplicates = data.duplicated()
# 删除重复数据
data_no_duplicates = data[~duplicates]
# 或者直接使用drop_duplicates方法
data_unique = data.drop_duplicates()
# 查看处理后的数据
print(data_no_duplicates.head())
四、数据集成
数据集成是将来自不同数据源的数据进行合并的过程。以下是一个使用Pandas进行数据集成的代码示例:
# 假设data1和data2是两个需要合并的Pandas DataFrame,且它们有一个共同的键'key'
# 使用merge函数进行内连接
merged_data = pd.merge(data1, data2, on='key', how='inner')
# 查看合并后的数据
print(merged_data.head())
五、部分代码展示
1:加载数据
这段代码是使用Python的pandas库来读取一个CSV文件,并将其存储为一个名为df_user的DataFrame对象。
import pandas as pd
df_user = pd.read_csv('D:\JUPYTER\工具\新用户表.csv',encoding='gbk')
2:缺失值处理
df_user
:这是一个DataFrame对象,它包含了从CSV文件中读取的数据。
isnull()
:这是pandas库中的一个方法,用于检查DataFrame中的每个元素是否为缺失值(NaN)。它会返回一个与原始DataFrame形状相同的布尔型DataFrame,其中True表示对应位置的元素是缺失值,False表示不是缺失值
sum()
:这是pandas库中的一个方法,用于对DataFrame或Series对象进行求和操作。在这里,它被应用于由isnull()
方法返回的布尔型DataFrame上。由于布尔型DataFrame中的True被视为1,False被视为0,所以sum()
方法会计算出每列中True的数量,即缺失值的数量。
综上所述,这段代码的作用是统计df_user中每一列的缺失值数量,并将结果以每列的名称和对应的缺失值数量的形式输出
df_user.isnull().sum()
运行结果如下:
3:异常值检测与处理
这段代码是用于读取一个Excel文件,并将其存储为名为df_car的DataFrame对象。
# 案例:处理汽车行驶里程表的异常值
df_car = pd.read_excel(r'D:\JUPYTER\工具\新能源汽车行驶里程表.xlsx')
df_car
df_car.describe() #查看各个序列的一些统计量
这段代码的目的是计算一个数据集中的行驶时长的正常区间值。具体解释如下:
Q1=df_car.describ()['行驶时长'][25%]
:这行代码从名为df_car
的DataFrame中提取了行驶时长列的描述性统计信息,并获取了第一四分位数(Q1)。
Q3=df_car.describ()['行驶时长']['25%']
:这行代码同样从df_car
中提取了行驶时长列的描述性统计信息,但这次获取的是第三四分位数(Q3)。
print(Q1,Q3)
:打印出Q1和Q3的值。
IQR = Q3 - Q1
:计算四分位距(Interquartile Range,IQR),即第三四分位数与第一四分位数之间的差值。
c = 3
:设置一个系数c,用于调整IQR的范围。
normal_low = Q1 - 1.5^{*} IQR
:计算正常区间的下限,即Q1减去1.5倍的IQR乘以系数c。
normal_high = Q3 + 1.5^{*} IQR
:计算正常区间的上限,即Q3加上1.5倍的IQR乘以系数c。
print(normal_low,normal_high)
:打印出正常区间的下限和上限。
# 获取序列的Q1\Q3
Q1=df_car.describe()['行驶时长']['25%']
Q3=df_car.describe()['行驶时长']['75%']
print(Q1,Q3)
#计算行驶时长的正常区间值
IQR = Q3 - Q1
c = 3 #人为调整的IQR系数
normal_low = Q1 - 1.5 * IQR
normal_high = Q3 +1.5 * IQR
print(normal_low,normal_high)
这段代码的目的是处理一个名为df_car
的DataFrame对象,删除其中行驶时长大于8180的数据行,并生成一个新的DataFrame对象df_car2
。具体解释如下:
df_car.query('行驶时长>8180')
:这行代码是一个被注释掉的条件查询语句,它原本用于筛选出行驶时长大于8180的数据行。由于被注释掉了,所以不会执行任何操作。
df_car2 = df_car.query('行驶时长<=8180').reset_index(drop=True)
:这行代码执行以下操作:
使用query()
函数对df_car
进行条件查询,筛选出行驶时长小于等于8180的数据行。
使用reset_index(drop=True)
方法重置索引,并将旧索引丢弃,生成一个新的DataFrame对象df_car2
。
df_car2
:打印或显示新的DataFrame对象df_car2
,其中不包含行驶时长大于8180的数据行。
综上所述,这段代码的目的是从原始的DataFrame对象df_car
中删除异常值(行驶时长大于8180的数据行),并生成一个新的DataFrame对象df_car2
,其中只包含正常范围内的数据行。
# 定位异常值,条件查询
#df_car.query('行驶时长>8180')
# 删除处理,以查询删除
df_car2 = df_car.query('行驶时长<=8180').reset_index(drop=True)
df_car2
异常处理前:
异常处理后:
4:重复数据的识别与删除
这段代码的目的是创建一个名为“df”的DataFrame,并对其进行处理以删除重复的姓名记录。具体解释如下:
df = pd.DataFrame(...)
: 这行代码使用pandas库中的DataFrame
函数创建一个新的DataFrame对象。传递给这个函数的数据是一个嵌套列表,其中每个子列表代表一行数据。在这个例子中,有三行数据,每行包含一个姓名和一个分数。
columns=['姓名','分数']
: 这个参数指定了DataFrame的列名,即第一行数据是'甲'和80,第二行数据是'甲'和85,第三行数据是'乙'和90。
df.drop_duplicates(subset=['姓名'], keep='first', inplace=True)
: 这行代码调用了DataFrame对象的drop_duplicates
方法,用于删除重复的行。subset=['姓名']
参数指定了要考虑哪些列来确定重复项,这里只考虑'姓名'列。keep='first'
参数表示保留第一次出现的重复项,而删除后续的重复项。inplace=True
参数表示直接在原始DataFrame上进行修改,而不是返回一个新的DataFrame。
df
: 最后一行代码打印出经过去重处理后的DataFrame。
综上所述,这段代码首先创建了一个包含姓名和分数的DataFrame,然后通过drop_duplicates
方法删除了重复的姓名记录,保留了每个姓名的第一个出现。最终的结果是一个没有重复姓名的DataFrame。
df = pd.DataFrame(
[['甲',80],['甲',85],['乙',90]],
columns=['姓名','分数']
)
df.drop_duplicates(subset=['姓名'],keep='first',inplace=True)
df
运行结果展示:
5:数据集成
这段代码通过多次左连接操作,将三个作业完成名单表的数据合并到全班名单表中,保留了所有学生的姓名信息,并将每个学生的作业完成情况整合在一起。
df_merge = pd.merge(df_0,df_1,how='left',on='姓名')
df_merge2 = pd.merge(df_merge,df_2,how='left',on='姓名')
df_merge3 = pd.merge(df_merge2,df_3,how='left',on='姓名')
df_merge3
运行结果如下:
六、学习心得体会:
在学习Python数据分析的过程中,我深刻体会到了数据预处理的重要性。数据预处理是数据分析的基石,它直接关系到后续分析的质量和准确性。通过这段时间的学习和实践,我掌握了使用Pandas库进行数据清洗、转换和编码的基本方法,学会了如何处理缺失值、异常值和重复数据,以及如何对数据进行规范化、标准化处理。我深刻认识到,只有高质量的数据输入,才能产生有价值的数据分析输出。未来,我将继续努力提升数据预处理能力,为更准确的数据分析打下基础。