MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python使用Pandas进行数据清洗

2021-06-141.2k 阅读

一、Pandas简介

Pandas是Python中一个功能强大且广泛使用的数据处理和分析库。它建立在NumPy之上,提供了高效的数据结构和数据分析工具,使得处理表格型数据变得轻而易举。在数据清洗的场景中,Pandas凭借其丰富的函数和方法,能够快速地对数据进行检测、修正和预处理,为后续的数据分析和建模奠定良好的基础。

Pandas的核心数据结构是Series(一维数据结构)和DataFrame(二维数据结构)。Series可以看作是带有标签的一维数组,而DataFrame则类似电子表格或SQL表,由多个Series组成,每列可以是不同的数据类型。这些数据结构使得我们能够方便地存储、操作和处理各种类型的数据集。

二、数据清洗概述

数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。在实际的数据收集过程中,数据往往存在各种问题,例如:

  1. 缺失值:数据集中某些值未被记录,可能是由于数据采集过程中的失误、传感器故障等原因导致。例如,在一份员工信息表中,部分员工的年龄字段可能为空。
  2. 重复值:数据集中出现完全相同的记录,这可能是由于数据录入重复或数据合并时出现问题。比如,在一份销售订单数据中,可能存在重复的订单记录。
  3. 异常值:与其他数据相比明显偏离的数据点,可能是由于数据录入错误或真实存在的极端情况。例如,在学生成绩数据中,出现了超过满分的成绩。
  4. 数据类型不一致:同一列的数据应该具有相同的数据类型,但可能由于数据采集或录入问题,导致数据类型不一致。比如,在日期列中,部分数据是日期格式,部分是字符串格式。

三、Python中使用Pandas进行数据清洗

(一)数据加载

在进行数据清洗之前,首先需要将数据加载到Pandas的DataFrame中。Pandas支持多种数据格式的读取,如CSV、Excel、SQL等。以下以CSV文件为例:

import pandas as pd

# 读取CSV文件
data = pd.read_csv('data.csv')

上述代码使用pd.read_csv函数将名为data.csv的文件读取到DataFrame对象data中。如果CSV文件有表头,Pandas会自动将第一行作为列名。如果文件没有表头,可以通过设置header=None参数,并在后续操作中手动指定列名。

(二)缺失值处理

  1. 检测缺失值 Pandas提供了isnull()notnull()方法来检测数据中的缺失值。isnull()方法返回一个与原DataFrame结构相同的布尔型DataFrame,其中缺失值对应的位置为True,非缺失值位置为False
import pandas as pd

data = pd.read_csv('data_with_missing.csv')
missing_values = data.isnull()
print(missing_values)
  1. 删除缺失值 可以使用dropna()方法删除包含缺失值的行或列。
# 删除包含缺失值的行
data_dropped = data.dropna(axis=0)

# 删除包含缺失值的列
data_dropped_columns = data.dropna(axis=1)

在上述代码中,axis=0表示按行删除,axis=1表示按列删除。dropna()方法还有其他参数,如how='all'表示只有当整行或整列全为缺失值时才删除,thresh=n表示至少有n个非缺失值的行或列才保留。

  1. 填充缺失值 除了删除缺失值,还可以选择填充缺失值。常用的填充方法有使用常数填充、使用均值、中位数等统计量填充。
# 使用常数填充
data_filled_constant = data.fillna(0)

# 使用均值填充数值型列
numeric_columns = data.select_dtypes(include=['number']).columns
data_filled_mean = data.copy()
for col in numeric_columns:
    mean_value = data[col].mean()
    data_filled_mean[col] = data[col].fillna(mean_value)

# 使用中位数填充数值型列
data_filled_median = data.copy()
for col in numeric_columns:
    median_value = data[col].median()
    data_filled_median[col] = data[col].fillna(median_value)

(三)重复值处理

  1. 检测重复值 使用duplicated()方法可以检测DataFrame中的重复行,返回一个布尔型Series,其中重复行对应的位置为True,首次出现的行对应的位置为False
import pandas as pd

data = pd.read_csv('data_with_duplicates.csv')
duplicate_rows = data.duplicated()
print(duplicate_rows)
  1. 删除重复值 通过drop_duplicates()方法可以删除DataFrame中的重复行。
data_unique = data.drop_duplicates()

默认情况下,drop_duplicates()方法会保留首次出现的行,删除后续的重复行。如果想保留最后一次出现的行,可以设置keep='last'参数。

(四)异常值处理

  1. 基于统计方法检测异常值 常用的基于统计方法检测异常值的方式有Z - Score方法和四分位数间距(IQR)方法。

Z - Score方法:Z - Score表示数据点与均值的距离,以标准差为单位。如果一个数据点的Z - Score绝对值大于某个阈值(通常为3),则可认为该数据点是异常值。

import pandas as pd
import numpy as np

data = pd.read_csv('data_with_outliers.csv')
numeric_columns = data.select_dtypes(include=['number']).columns

for col in numeric_columns:
    mean = data[col].mean()
    std = data[col].std()
    z_scores = np.abs((data[col] - mean) / std)
    data[col] = np.where(z_scores > 3, mean, data[col])

在上述代码中,对于每一个数值型列,计算其Z - Score,将Z - Score绝对值大于3的数据点替换为该列的均值。

IQR方法:IQR是上四分位数(Q3)与下四分位数(Q1)之间的差值。异常值通常被定义为小于Q1 - 1.5 * IQR或大于Q3 + 1.5 * IQR的数据点。

import pandas as pd

data = pd.read_csv('data_with_outliers.csv')
numeric_columns = data.select_dtypes(include=['number']).columns

for col in numeric_columns:
    Q1 = data[col].quantile(0.25)
    Q3 = data[col].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    data[col] = np.where((data[col] < lower_bound) | (data[col] > upper_bound), np.nan, data[col])

上述代码中,对于每个数值型列,计算IQR,并确定上下界,将超出上下界的数据点设置为缺失值,后续可以按照缺失值的处理方法进行处理。

  1. 基于机器学习算法检测异常值 一些机器学习算法也可以用于检测异常值,如Isolation Forest(孤立森林)算法。Isolation Forest通过随机选择一个特征和该特征上的一个值,将数据集划分为两部分,不断重复这个过程,直到每个数据点都被孤立。异常值通常会在较少的划分步骤中被孤立。
import pandas as pd
from sklearn.ensemble import IsolationForest

data = pd.read_csv('data_with_outliers.csv')
numeric_columns = data.select_dtypes(include=['number'])

clf = IsolationForest(contamination=0.1)
outlier_pred = clf.fit_predict(numeric_columns)
data['outlier'] = outlier_pred
data = data[data['outlier'] == 1]
data = data.drop(columns=['outlier'])

在上述代码中,使用IsolationForest模型进行异常值检测,contamination参数表示数据集中异常值的比例。预测结果为 - 1表示异常值,1表示正常值。最后将异常值对应的行删除。

(五)数据类型转换

Pandas中的数据类型有多种,如object(通常用于字符串)、int64float64等。在数据清洗过程中,常常需要将数据转换为合适的数据类型。

  1. 转换为数值型 当数据集中的数值列被误读为字符串类型时,需要将其转换为数值型。可以使用pd.to_numeric()函数。
import pandas as pd

data = pd.read_csv('data_with_wrong_dtype.csv')
data['numeric_column'] = pd.to_numeric(data['numeric_column'], errors='coerce')

在上述代码中,errors='coerce'表示如果转换失败,将该值设置为缺失值NaN

  1. 转换为日期型 如果数据集中包含日期列,但数据类型不是日期型,可以使用pd.to_datetime()函数进行转换。
data['date_column'] = pd.to_datetime(data['date_column'])

转换为日期型后,可以方便地进行日期相关的操作,如提取年份、月份等。

data['year'] = data['date_column'].dt.year
data['month'] = data['date_column'].dt.month

(六)数据标准化和归一化

数据标准化和归一化是将数据按照一定的规则进行转换,使其具有统一的尺度和分布。常见的方法有Min - Max归一化和Z - Score标准化。

  1. Min - Max归一化 Min - Max归一化将数据映射到[0, 1]区间内,公式为:$x_{norm}=\frac{x - x_{min}}{x_{max}-x_{min}}$
import pandas as pd
import numpy as np

data = pd.read_csv('data_to_normalize.csv')
numeric_columns = data.select_dtypes(include=['number']).columns

for col in numeric_columns:
    min_value = data[col].min()
    max_value = data[col].max()
    data[col] = (data[col] - min_value) / (max_value - min_value)
  1. Z - Score标准化 Z - Score标准化将数据转换为均值为0,标准差为1的分布,公式为:$z=\frac{x - \mu}{\sigma}$
for col in numeric_columns:
    mean = data[col].mean()
    std = data[col].std()
    data[col] = (data[col] - mean) / std

四、数据清洗实战案例

假设我们有一份电商销售数据,包含订单编号、客户ID、产品名称、价格、购买数量、购买日期等信息。数据文件为ecommerce_sales.csv,但该数据存在缺失值、重复值、异常值以及数据类型不一致等问题。

import pandas as pd
import numpy as np

# 加载数据
data = pd.read_csv('ecommerce_sales.csv')

# 缺失值处理
missing_values = data.isnull().sum()
print("缺失值情况:\n", missing_values)

data = data.dropna(axis=0)

# 重复值处理
duplicate_rows = data.duplicated().sum()
print("重复行数:", duplicate_rows)

data = data.drop_duplicates()

# 异常值处理 - 基于IQR检测价格异常值
Q1 = data['价格'].quantile(0.25)
Q3 = data['价格'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
data['价格'] = np.where((data['价格'] < lower_bound) | (data['价格'] > upper_bound), np.nan, data['价格'])
data = data.dropna(subset=['价格'])

# 数据类型转换 - 将购买数量转换为整数
data['购买数量'] = data['购买数量'].astype(int)

# 将购买日期转换为日期型
data['购买日期'] = pd.to_datetime(data['购买日期'])

# 数据标准化 - 对价格进行Z - Score标准化
mean_price = data['价格'].mean()
std_price = data['价格'].std()
data['价格标准化'] = (data['价格'] - mean_price) / std_price

print(data.head())

通过上述代码,我们对电商销售数据进行了全面的数据清洗,包括缺失值、重复值、异常值处理,数据类型转换以及数据标准化等操作,使得数据更加规范和适合后续的分析。

五、总结与注意事项

使用Pandas进行数据清洗是数据预处理过程中至关重要的环节。通过上述介绍的各种方法和案例,我们可以有效地处理数据中存在的各种问题。在实际应用中,需要注意以下几点:

  1. 备份数据:在进行数据清洗操作之前,务必备份原始数据,以免清洗过程中出现错误导致数据丢失或损坏。
  2. 理解数据:在进行数据清洗之前,要充分理解数据的背景和含义,以便更准确地处理缺失值、异常值等问题。例如,对于某些业务场景,异常值可能是真实存在的特殊情况,不能简单地删除或修正。
  3. 记录操作:记录每一步数据清洗操作,包括操作的原因、使用的方法和参数等。这不仅有助于调试和检查,也方便后续的数据审计和重复使用。
  4. 逐步验证:在进行复杂的数据清洗操作时,建议逐步进行,并在每一步操作后验证数据的正确性,避免累积错误导致最终结果不准确。

通过合理运用Pandas的功能和遵循上述注意事项,可以高效地完成数据清洗任务,为后续的数据挖掘、机器学习等工作提供高质量的数据基础。