跳至主要內容

数据清洗

blacklad大约 5 分钟PythonPythonPandas

数据清洗

1 介绍

数据清洗是数据分析和机器学习过程中的重要步骤。它涉及识别和修正数据中的错误或不一致,使数据更适合用于分析。一个好的数据集应该尽量减少噪声、缺失值、重复项等问题。

1.1 数据问题

  • 缺失值:数据集中某些观测值未被记录。
  • 重复数据:数据集中相同记录出现多次。
  • 错误或异常值:数据集中与其他值明显不同的观测值。
  • 数据不一致性:数据中的格式、单位、编码等不一致。
  • 不规范的数据格式:数据格式不符合预期的要求。

1.2 数据准备

import pandas as pd
import numpy as np

# 创建示例数据
data = {
    '姓名': ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank', 'Grace', 'Henry'],
    '成绩': [85, np.nan, 70, 92, None, 65, 78, 80],
    '学科': ['Math', 'English', 'Physics', 'Chemistry', 'Biology', 'History', 'Geography', 'Physics'],
    '学期': ['2023-1', '2023-2', '2023-1', '2023-2', '2023-1', '2023-2', '2023-1', '2023-1']
}

# 创建DataFrame
df = pd.DataFrame(data)

# 添加一些重复数据和错误数据
df = df.append({'姓名': 'Alice', '成绩': 90, '学科': 'Math', '学期': '2023-1'}, ignore_index=True)
df = df.append({'姓名': 'Bob', '成绩': 75, '学科': 'English', '学期': '2023-2'}, ignore_index=True)

原始数据如下

姓名成绩学科学期
0Alice85.0Math2023-1
1BobNaNEnglish2023-2
2Charlie70.0Physics2023-1
3David92.0Chemistry2023-2
4EvaNoneBiology2023-1
5Frank65History2023-2
6Grace78.0Geography2023-1
7Henry80.0Physics2023-1
8Alice90.0Math2023-1
9Bob75.0English2023-2

2 缺失值处理

由于数据来源的复杂性与不确定性,数据中难免会存在字段值不全、缺失等情况。

2.1 查看

在处理缺失值之前,首先要了解数据集中是否存在缺失值。

查看每列缺失值的数量:

print(df.isnull().sum())
姓名    0
成绩    2
学科    0
学期    0
dtype: int64

数据集中总缺失值数量

print(df.isnull().sum().sum())
2

查看缺失值的位置

# 以布尔形式返回缺失值的位置
print(df.isnull())
      姓名     成绩     学科     学期
0  False  False  False  False
1  False   True  False  False
2  False  False  False  False
3  False  False  False  False
4  False   True  False  False
5  False  False  False  False
6  False  False  False  False
7  False  False  False  False
8  False  False  False  False
9  False  False  False  False

2.2 缺失值筛选

可以筛选出缺失值的位置。

print(df[df.isna().any(1)])
    姓名  成绩       学科      学期
1  Bob NaN  English  2023-2
4  Eva NaN  Biology  2023-1

2.2 删除重复数据

对于某些情况下,可能需要直接删除包含缺失值的行或列。

删除包含缺失值的行

df_dropped_rows = df.dropna()
print(df_dropped_rows)
        姓名    成绩     学科      学期
0    Alice  85.0       Math  2023-1
2  Charlie  70.0    Physics  2023-1
3    David  92.0  Chemistry  2023-2
5    Frank  65.0    History  2023-2
6    Grace  78.0  Geography  2023-1
7    Henry  80.0    Physics  2023-1
8    Alice  90.0       Math  2023-1
9      Bob  75.0    English  2023-2

删除包含缺失值的列

df_dropped_columns = df.dropna(axis=1)
print(df_dropped_columns)
        姓名      学科      学期
0    Alice       Math  2023-1
1      Bob    English  2023-2
2  Charlie    Physics  2023-1
3    David  Chemistry  2023-2
4      Eva    Biology  2023-1
5    Frank    History  2023-2
6    Grace  Geography  2023-1
7    Henry    Physics  2023-1
8    Alice       Math  2023-1
9      Bob    English  2023-2

2.3 填充

另一种处理缺失值的方法是用其他合理的值填充它们。

df['成绩'].fillna(df['成绩'].mean())
print(df)
        姓名      成绩         学科      学期
0    Alice  85.000       Math  2023-1
1      Bob  79.375    English  2023-2
2  Charlie  70.000    Physics  2023-1
3    David  92.000  Chemistry  2023-2
4      Eva  79.375    Biology  2023-1
5    Frank  65.000    History  2023-2
6    Grace  78.000  Geography  2023-1
7    Henry  80.000    Physics  2023-1
8    Alice  90.000       Math  2023-1
9      Bob  75.000    English  2023-2

也可以使用其他的值填充。

# 用指定值填充
df_filled_value = df.fillna(0)

# 用前一个有效值填充
df_filled_forward = df.fillna(method='ffill')

# 用后一个有效值填充
df_filled_backward = df.fillna(method='bfill')

2.4 插值填充

可以通过插值的方法填充数据,默认为线性插值,根据数据的前后两个数字计算。

s = pd.Series([0, 5, np.nan, 7])

# 插值填充
s.interpolate()
0    0.0
1    5.0
2    6.0
3    7.0
dtype: float64

3 重复值的处理

3.1 筛选重复值

在数据清洗过程中,使用 duplicated 方法可以识别数据中的重复值。

subset是指定需要判断重复的列,这里不考虑成绩列。

print(df.duplicated(subset=['姓名', '学科', '学期']))

可以看到最后两行与前面的重复。

0    False
1    False
2    False
3    False
4    False
5    False
6    False
7    False
8     True
9     True
dtype: bool

获取所有重复行

duplicates = df[df.duplicated(subset=['姓名', '学科', '学期'])]
    姓名   成绩     学科      学期
8  Alice  90.0     Math  2023-1
9    Bob  75.0  English  2023-2

3.2 删除重复值

对于重复值,可以选择删除它们。

df_no_duplicates_subset = df.drop_duplicates(subset=['姓名', '学科', '学期'])
print(df_no_duplicates_subset)
        姓名    成绩         学科      学期
0    Alice  85.0       Math  2023-1
1      Bob   NaN    English  2023-2
2  Charlie  70.0    Physics  2023-1
3    David  92.0  Chemistry  2023-2
4      Eva   NaN    Biology  2023-1
5    Frank  65.0    History  2023-2
6    Grace  78.0  Geography  2023-1
7    Henry  80.0    Physics  2023-1

4 数据格式转换

确保数据以正确的数据类型存储,如使用 astype() 方法设置数据类型,使用 to_datetime() 将字符串转换为日期时间类型。

4.1 数字类型

注意先将nan值给处理后再进行后续的试验。

df.loc[3, '成绩'] = '65.5'
df.loc[5, '成绩'] = '33'
print(df['成绩'])
# 将字符串列转换为浮点数
print(df['成绩'].astype(float))
0    85.0
2    70.0
3    65.5
5      33
6    78.0
7    80.0
8    90.0
9    75.0
Name: 成绩, dtype: object
0    85.0
2    70.0
3    65.5
5    33.0
6    78.0
7    80.0
8    90.0
9    75.0
Name: 成绩, dtype: float64

4.2 时间类型转换

将字符串的时间类型转换为datetime64类型

import pandas as pd

# 创建一个包含不同数据类型的 DataFrame
data = {'A': ['2023-01-01', '2023-01-02', '2023-01-03']}
df = pd.DataFrame(data)


# 将字符串列转换为日期时间类型
df['A'] = pd.to_datetime(df['A'])

print(df.dtypes)
A    datetime64[ns]
dtype: object
上次编辑于:
贡献者: blacklad