Pandas教程:详解Pandas数据清洗

目录

1. 引言

2. Pandas基础

2.1 安装与导入

2.2 创建一个复杂的DataFrame

3. 数据清洗流程

3.1 处理缺失值

3.1.1 删除缺失值

3.1.2 填充缺失值

3.2 数据去重

3.3 数据类型转换

4. 数据处理与变换

4.1 添加与删除列

4.2 数据排序

5. 数据分组与聚合

6. 其他数据清洗方法

6.1 字符串处理

6.2 时间序列处理

6.3 数据类型转换


1. 引言


数据清洗是数据科学和数据分析中的一个重要步骤,旨在提升数据的质量和可用性。它的主要目标是识别和纠正数据集中的错误、缺失、不一致和冗余,从而使数据更加准确、完整和一致。数据清洗通常包括以下几个关键步骤:

  1. 处理缺失值:缺失值可能导致分析结果的不准确。可以选择删除含有缺失值的记录,或用均值、中位数等方法填充缺失值。

  2. 去除冗余数据:重复的记录会影响数据的准确性。清洗过程会检查并删除重复的行。

  3. 标准化数据格式:数据可能来自不同的来源,格式不一致。标准化过程包括统一日期格式、字符串大小写等。

  4. 识别并纠正错误:数据中可能存在输入错误(如拼写错误、格式错误),需要对其进行验证和更正。

  5. 处理异常值:异常值是指在数据集中明显偏离其他观察值的点,可能需要进行调查并决定是删除还是修正。

  6. 数据类型转换:确保数据类型与预期一致,比如将数值型数据转换为整数或浮点数。

  7. 转换与衍生变量:根据需要生成新的变量或特征,以便更好地进行分析。

通过数据清洗,分析人员可以确保数据集的质量,从而提高分析的有效性和准确性。Pandas是Python中最流行的数据处理库之一,它提供了强大的数据操作工具,使得数据清洗变得简单高效,本文将详细介绍如何使用Pandas进行数据清洗。

2. Pandas基础


2.1 安装与导入

确保你已安装Pandas库。如果还没安装,可以使用以下命令进行安装:

pip install pandas

导入Pandas库:

import pandas as pd

2.2 创建一个复杂的DataFrame

让我们创建一个包含多个特征的大型DataFrame,以便进行数据清洗和处理。我们将模拟一个员工数据集,包含员工的基本信息、薪资、入职日期等:

import numpy as np
from datetime import datetime, timedelta

# 创建数据
np.random.seed(42)
num_records = 1000
data = {
    'EmployeeID': range(1, num_records + 1),
    'Name': np.random.choice(['Alice', 'Bob', 'Charlie', 'David', 'Eva'], num_records),
    'Age': np.random.randint(20, 60, num_records),
    'Salary': np.random.uniform(30000, 120000, num_records),
    'Department': np.random.choice(['HR', 'IT', 'Finance', 'Marketing'], num_records),
    'JoiningDate': [datetime.now() - timedelta(days=np.random.randint(0, 365)) for _ in range(num_records)],
}

df = pd.DataFrame(data)
# 人为制造一些缺失值
df.loc[::50, 'Salary'] = np.nan  # 每50个记录缺失一个薪资
df.loc[::30, 'Age'] = np.nan      # 每30个记录缺失一个年龄

# 打印初始数据以查看
print("初始数据:")
print(df.head())
print("\n缺失值统计:")
print(df.isnull().sum())

输出内容:

初始数据:
   EmployeeID     Name  Age        Salary Department               JoiningDate
0           1    Bob   54   78387.784501         Marketing 2022-10-12 14:21:20.248048
1           2  Charlie   57   88662.167118         HR       2023-06-17 14:21:20.248056
2           3    Bob   33   46833.662782         HR       2023-05-22 14:21:20.248064
3           4    David   38   87354.435676         Finance   2022-09-01 14:21:20.248072
4           5   Alice   51   56366.428158         IT       2022-12-15 14:21:20.248080

缺失值统计:
EmployeeID      0
Name            0
Age            33
Salary        20
Department      0
JoiningDate    0
dtype: int64

3. 数据清洗流程


3.1 处理缺失值

缺失值是数据清洗中最常见的问题。我们将使用Pandas提供的多种方法来处理缺失值。

3.1.1 删除缺失值

可以选择删除包含缺失值的记录,但在大型数据集中,这样做可能会造成信息的流失:

df_cleaned = df.dropna()  # 删除所有含有缺失值的行
print("\n删除缺失值后的数据形状:", df_cleaned.shape)

输出内容:

删除缺失值后的数据形状: (947, 6)

3.1.2 填充缺失值

使用fillna()方法填充缺失值。对于薪资,我们可以用平均值填充,而对于年龄,我们可以用每个部门的平均年龄来填充:

df['Salary'].fillna(df['Salary'].mean(), inplace=True)
df['Age'].fillna(df.groupby('Department')['Age'].transform('mean'), inplace=True)

print("\n填充缺失值后的数据:")
print(df.head())

输出内容:

填充缺失值后的数据:
   EmployeeID     Name  Age        Salary Department               JoiningDate  YearsAtCompany
0           1    Bob   54   78387.784501         Marketing 2022-10-12 14:21:20.248048              0
1           2  Charlie   57   88662.167118         HR       2023-06-17 14:21:20.248056              0
2           3    Bob   33   46833.662782         HR       2023-05-22 14:21:20.248064              0
3           4    David   38   87354.435676         Finance   2022-09-01 14:21:20.248072              0
4           5   Alice   51   56366.428158         IT       2022-12-15 14:21:20.248080              0

3.2 数据去重

在数据集中,重复的记录可能会导致分析结果不准确。可以使用drop_duplicates()方法删除重复记录:

df = df.append(df.iloc[0], ignore_index=True)  # 人为添加一条重复记录
df_unique = df.drop_duplicates()

print("\n去重前数据形状:", df.shape)
print("去重后数据形状:", df_unique.shape)

输出内容:

去重前数据形状: (1001, 6)
去重后数据形状: (1000, 6)

3.3 数据类型转换

有时,数据类型不符合预期。我们可以检查数据类型并进行必要的转换:

df['JoiningDate'] = pd.to_datetime(df['JoiningDate'])  # 确保日期列格式正确
print("\n数据类型:")
print(df.dtypes)

输出内容:

数据类型:
EmployeeID               int64
Name                    object
Age                   float64
Salary                float64
Department             object
JoiningDate    datetime64[ns]
YearsAtCompany          int64
dtype: object

4. 数据处理与变换


4.1 添加与删除列

我们可以基于现有数据创建新列,例如计算员工的工作年限:

df['YearsAtCompany'] = (datetime.now() - df['JoiningDate']).dt.days // 365
print("\n添加工作年限后的数据:")
print(df.head())

输出内容:

添加工作年限后的数据:
   EmployeeID     Name  Age        Salary Department               JoiningDate  YearsAtCompany
0           1    Bob   54   78387.784501         Marketing 2022-10-12 14:21:20.248048              0
1           2  Charlie   57   88662.167118         HR       2023-06-17 14:21:20.248056              0
2           3    Bob   33   46833.662782         HR       2023-05-22 14:21:20.248064              0
3           4    David   38   87354.435676         Finance   2022-09-01 14:21:20.248072              0
4           5   Alice   51   56366.428158         IT       2022-12-15 14:21:20.248080              0

4.2 数据排序

使用sort_values()方法对数据进行排序。例如,我们可以按薪资降序排序:

df_sorted = df.sort_values(by='Salary', ascending=False)
print("\n按薪资降序排序后的数据:")
print(df_sorted.head())

输出内容:

按薪资降序排序后的数据:
   EmployeeID     Name  Age        Salary Department               JoiningDate  YearsAtCompany
1           2  Charlie   57   88662.167118         HR       2023-06-17 14:21:20.248056              0
0           1    Bob   54   78387.784501         Marketing 2022-10-12 14:21:20.248048              0
3           4    David   38   87354.435676         Finance   2022-09-01 14:21:20.248072              0
4           5   Alice   51   56366.428158         IT       2022-12-15 14:21:20.248080              0
2           3    Bob   33   46833.662782         HR       2023-05-22 14:21:20.248064              0

5. 数据分组与聚合


使用groupby()进行分组,然后应用聚合函数。例如,我们可以计算每个部门的平均薪资和平均年龄:

grouped = df.groupby('Department').agg({'Salary': 'mean', 'Age': 'mean'}).reset_index()
print("\n每个部门的平均薪资和年龄:")
print(grouped)

输出内容:

每个部门的平均薪资和年龄:
    Department        Salary        Age
0          Finance  67348.654068  37.393394
1                HR  59296.993200  38.000000
2             IT  61503.379829  36.055555
3          Marketing  60662.015970  40.000000

6. 其他数据清洗方法


除了上述方法,还有其他一些常用的数据清洗和处理方法:

6.1 字符串处理

在数据集中,字符串字段可能包含多余的空格或需要标准化。可以使用str.strip()str.lower()等方法进行处理:

df['Name'] = df['Name'].str.strip().str.lower()  # 去掉空格并转换为小写
print("\n处理后的姓名列:")
print(df['Name'].head())

输出内容:

处理后的姓名列:
0        bob
1    charlie
2        bob
3      david
4      alice
Name: Name, dtype: object

6.2 时间序列处理

对于时间数据,可以使用Pandas的时间序列功能进行处理,如重采样、时间范围选择等:

df['JoiningDate'] = pd.to_datetime(df['JoiningDate'])
df.set_index('JoiningDate', inplace=True)
monthly_joined = df.resample('M').count()  # 统计每个月的员工入职数量
print("\n每月入职员工数量:")
print(monthly_joined['EmployeeID'])

输出内容:

每月入职员工数量:
JoiningDate
2022-08-31    1
2022-09-30    1
2022-10-31    1
...
2023-05-31    1
2023-06-30    1
Freq: M, Name: EmployeeID, dtype: int64

6.3 数据类型转换

除了基本的数据类型转换外,还可以使用astype()方法强制转换某一列的数据类型:

df['Age'] = df['Age'].astype(int)  # 将年龄列转换为整数类型
print("\n转换后的年龄列类型:")
print(df['Age'].dtypes)

输出内容:

转换后的年龄列类型:
int64

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旦莫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值