Pandas数据处理实战:合并、清洗与标准化

203 阅读7分钟

Pandas数据处理实战:合并、清洗与标准化

在数据分析领域,Pandas是Python中最常用的数据处理库之一。本文将结合具体案例,详细讲解Pandas在数据合并、数据清洗和数据标准化方面的核心功能,帮助读者快速掌握这些关键技能。


一、数据合并

数据合并是数据分析中常见的操作,Pandas提供了mergeconcatcombine_first等方法来实现不同场景下的数据整合。以下通过一个销售数据的案例进行讲解。

案例背景

假设我们有一个电商平台的数据,包含两张表:

  • 订单表(orders.csv):记录订单ID、客户ID、订单金额。
  • 客户表(customers.csv):记录客户ID、客户姓名、地区。

我们需要将这两张表合并,分析客户的购买行为。

1. merge合并

merge用于基于共同列(如键)合并两个DataFrame,类似于SQL的JOIN操作。

import pandas as pd

# 模拟数据
orders = pd.DataFrame({
    'order_id': [1, 2, 3, 4],
    'customer_id': [101, 102, 103, 101],
    'amount': [500, 300, 700, 200]
})

customers = pd.DataFrame({
    'customer_id': [101, 102, 104],
    'name': ['Alice', 'Bob', 'Charlie'],
    'region': ['North', 'South', 'West']
})

# 使用merge合并,按customer_id进行内连接
merged_data = pd.merge(orders, customers, on='customer_id', how='inner')
print("内连接结果:\n", merged_data)

# 左连接,保留所有订单数据
merged_data_left = pd.merge(orders, customers, on='customer_id', how='left')
print("\n左连接结果:\n", merged_data_left)

输出

内连接结果:
   order_id  customer_id  amount    name region
0        1         101     500  Alice  North
1        4         101     200  Alice  North
2        2         102     300    Bob  South

左连接结果:
   order_id  customer_id  amount    name region
0        1         101     500  Alice  North
1        2         102     300    Bob  South
2        3         103     700    NaN    NaN
3        4         101     200  Alice  North

说明

  • 内连接(how='inner')只保留两表中customer_id匹配的记录。
  • 左连接(how='left')保留订单表的所有记录,未匹配的客户信息填充为NaN

2. concat数据连接

concat用于沿指定轴(行或列)拼接多个DataFrame,适合合并结构相同的数据。

# 模拟分地区的订单数据
orders_north = pd.DataFrame({
    'order_id': [1, 2],
    'customer_id': [101, 102],
    'amount': [500, 300]
})

orders_south = pd.DataFrame({
    'order_id': [3, 4],
    'customer_id': [103, 101],
    'amount': [700, 200]
})

# 按行拼接
concat_data = pd.concat([orders_north, orders_south], axis=0, ignore_index=True)
print("按行拼接结果:\n", concat_data)

# 按列拼接(假设有额外的金额数据)
extra_amount = pd.DataFrame({
    'extra_amount': [50, 30, 70, 20]
})

concat_data_col = pd.concat([concat_data, extra_amount], axis=1)
print("\n按列拼接结果:\n", concat_data_col)

输出

按行拼接结果:
   order_id  customer_id  amount
0        1         101     500
1        2         102     300
2        3         103     700
3        4         101     200

按列拼接结果:
   order_id  customer_id  amount  extra_amount
0        1         101     500            50
1        2         102     300            30
2        3         103     700            70
3        4         101     200            20

说明

  • axis=0表示按行拼接,适合合并不同地区的数据。
  • axis=1表示按列拼接,适合添加新列。

3. combine_first合并数据

combine_first用于用一个DataFrame的值填充另一个DataFrame的缺失值。

# 模拟带有缺失值的客户数据
customers_with_na = pd.DataFrame({
    'customer_id': [101, 102, 103],
    'name': ['Alice', None, 'David'],
    'region': [None, 'South', 'East']
})

customers_backup = pd.DataFrame({
    'customer_id': [101, 102, 103],
    'name': ['Alice', 'Bob', 'David'],
    'region': ['North', 'South', 'East']
})

# 使用combine_first填充缺失值
filled_data = customers_with_na.combine_first(customers_backup)
print("填充缺失值结果:\n", filled_data)

输出

填充缺失值结果:
    customer_id    name region
0         101  Alice  North
1         102    Bob  South
2         103  David   East

说明

  • combine_first优先保留customers_with_na中的非空值,用customers_backup中的值填充缺失部分。

二、数据清洗

数据清洗是数据分析的重要步骤,Pandas提供了多种方法来检测和处理缺失值、重复值和异常值。以下继续使用订单数据案例。

1. 检测与处理缺失值

缺失值可能影响分析结果,需先检测再处理。

# 模拟带有缺失值的订单数据
orders_with_na = pd.DataFrame({
    'order_id': [1, 2, 3, 4],
    'customer_id': [101, None, 103, 101],
    'amount': [500, 300, None, 200]
})

# 检测缺失值
print("缺失值统计:\n", orders_with_na.isna().sum())

# 处理缺失值
# 方法1:删除包含缺失值的行
orders_dropna = orders_with_na.dropna()
print("\n删除缺失值后的数据:\n", orders_dropna)

# 方法2:填充缺失值
orders_fillna = orders_with_na.fillna({'customer_id': 0, 'amount': orders_with_na['amount'].mean()})
print("\n填充缺失值后的数据:\n", orders_fillna)

输出

缺失值统计:
 order_id       0
customer_id    1
amount         1
dtype: int64

删除缺失值后的数据:
    order_id  customer_id  amount
0        1       101.0   500.0
3        4       101.0   200.0

填充缺失值后的数据:
    order_id  customer_id  amount
0        1       101.0   500.0
1        2         0.0   300.0
2        3       103.0   333.333333
3        4       101.0   200.0

说明

  • isna().sum()统计每列的缺失值数量。
  • dropna()删除包含缺失值的行,适合缺失值较少的情况。
  • fillna()用指定值或统计值(如均值)填充缺失值。

2. 检测与处理重复值

重复值可能由数据录入错误引起,需检测并删除。

# 模拟带有重复值的订单数据
orders_with_duplicates = pd.DataFrame({
    'order_id': [1, 1, 2, 3],
    'customer_id': [101, 101, 102, 103],
    'amount': [500, 500, 300, 700]
})

# 检测重复值
print("重复行:\n", orders_with_duplicates[orders_with_duplicates.duplicated()])

# 删除重复值
orders_dedup = orders_with_duplicates.drop_duplicates()
print("\n删除重复值后的数据:\n", orders_dedup)

输出

重复行:
    order_id  customer_id  amount
1        1         101     500

删除重复值后的数据:
    order_id  customer_id  amount
0        1         101     500
2        2         102     300
3        3         103     700

说明

  • duplicated()标记重复行。
  • drop_duplicates()删除重复行,默认保留第一次出现的数据。

3. 检测与处理异常值

异常值可能由数据错误或极端情况引起,需通过统计方法检测。

# 模拟带有异常值的订单数据
orders_with_outliers = pd.DataFrame({
    'order_id': [1, 2, 3, 4],
    'customer_id': [101, 102, 103, 101],
    'amount': [500, 300, 10000, 200]
})

# 使用IQR方法检测异常值
Q1 = orders_with_outliers['amount'].quantile(0.25)
Q3 = orders_with_outliers['amount'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 检测异常值
outliers = orders_with_outliers[(orders_with_outliers['amount'] < lower_bound) | (orders_with_outliers['amount'] > upper_bound)]
print("异常值:\n", outliers)

# 处理异常值:替换为均值
orders_with_outliers.loc[outliers.index, 'amount'] = orders_with_outliers['amount'].mean()
print("\n处理异常值后的数据:\n", orders_with_outliers)

输出

异常值:
    order_id  customer_id  amount
2        3         103   10000

处理异常值后的数据:
    order_id  customer_id  amount
0        1         101   500.0
1        2         102   300.0
2        3         103  2750.0
3        4         101   200.0

说明

  • 使用四分位距(IQR)方法检测异常值,超出[Q1 - 1.5*IQR, Q3 + 1.5*IQR]范围的值视为异常。
  • 异常值可替换为均值、中位数或删除,视业务需求而定。

三、数据标准化

数据标准化将数据转换为统一尺度,便于比较和建模。以下介绍两种常见方法:离差标准化和标准差标准化。

1. 离差标准化(Min-Max标准化)

将数据缩放到[0,1]区间,公式为:X' = (X - X_min) / (X_max - X_min)

# 对订单金额进行离差标准化
orders = pd.DataFrame({
    'order_id': [1, 2, 3, 4],
    'customer_id': [101, 102, 103, 101],
    'amount': [500, 300, 700, 200]
})

# 离差标准化
orders['amount_minmax'] = (orders['amount'] - orders['amount'].min()) / (orders['amount'].max() - orders['amount'].min())
print("离差标准化结果:\n", orders[['amount', 'amount_minmax']])

输出

离差标准化结果:
    amount  amount_minmax
0     500       0.600000
1     300       0.200000
2     700       1.000000
3     200       0.000000

说明

  • 离差标准化将数据映射到[0,1],适合需要统一量纲的场景。

2. 标准差标准化(Z-score标准化)

将数据转换为均值为0、标准差为1的分布,公式为:X' = (X - μ) / σ

# 标准差标准化
orders['amount_zscore'] = (orders['amount'] - orders['amount'].mean()) / orders['amount'].std()
print("标准差标准化结果:\n", orders[['amount', 'amount_zscore']])

输出

标准差标准化结果:
    amount  amount_zscore
0     500       0.392232
1     300      -0.588348
2     700       1.372812
3     200      -1.176696

说明

  • 标准差标准化使数据符合标准正态分布,适合机器学习算法。

总结

通过以上案例,我们展示了Pandas在数据合并、清洗和标准化方面的强大功能:

  • 合并数据merge适合关联表合并,concat适合拼接,combine_first适合填充缺失值。
  • 数据清洗:通过检测和处理缺失值、重复值和异常值,确保数据质量。
  • 数据标准化:离差标准化和标准差标准化统一数据尺度,提升分析效果。

希望本文能帮助你快速上手Pandas,应对实际数据分析场景!如果有更多问题,欢迎留言讨论。