趋近智
数据,特别是从数据库、API 和网页抓取等多种来源收集的数据,很少以完美的、可供分析的状态呈现。虽然对缺失值或不正确数据类型进行基本检查是必不可少的,但有效的数据准备通常需要更精细的清洗技术。这里介绍了识别和解决复杂数据质量问题的方法,这些问题可能对后续分析和模型表现造成重大影响。
请考虑简单的缺失值填充或删除完全重复的行。我们将处理需要仔细考量的细微不一致、结构性问题和异常值。
在应用高级清洗方法之前,您首先需要找出这些更难察觉的问题。常见问题包括:
user_id 与 UserID)、同一字段的数据类型冲突或意料之外的数据配置。我们来瞧瞧使用 Python 库(如 Pandas)应对这些难题的实际方法。
识别近似重复通常涉及计算字符串相似度得分。thefuzz(前身为 fuzzywuzzy)等库提供相关函数。
# thefuzz 使用示例(安装命令:pip install thefuzz)
from thefuzz import fuzz
from thefuzz import process
# 潜在重复公司名称的示例列表
company_names = ["Tech Corp Inc.", "Tech Corp Incorporated", "Global Systems Ltd", "TechCorp Inc", "Global Systems Limited"]
# 查找与 'Tech Corp Inc.' 相似度高于特定阈值的匹配项
matches = process.extract("Tech Corp Inc.", company_names, limit=3, scorer=fuzz.token_sort_ratio)
print(f"Potential matches for 'Tech Corp Inc.': {matches}")
# 输出可能为:[('Tech Corp Inc.', 100), ('TechCorp Inc', 95), ('Tech Corp Incorporated', 88)]
# 然后可以根据得分定义逻辑来标准化这些名称
这需要仔细调整相似度阈值,并可能需要人工审核,以避免错误合并不同的条目。
Pandas 字符串方法,常使用正则表达式,对于清洗不一致的文本和格式非常有用。
import pandas as pd
import re
data = {'product_id': ['SKU-123-A', 'sku 456 B', 'SKU - 789 - C', 'SKU:999D'],
'order_date': ['10/26/2023', '2023-10-27', '28 Oct 2023', '2023/10/29']}
df = pd.DataFrame(data)
# 将产品ID标准化为 'SKU-XXX-X' 格式
def standardize_sku(sku):
# 移除空格、连字符、冒号并转换为大写
cleaned_sku = re.sub(r'[\s:-]+', '', sku).upper()
# 找到数字和最后一个字母/字符
match = re.search(r'SKU(\d+)(\w)$', cleaned_sku)
if match:
return f"SKU-{match.group(1)}-{match.group(2)}"
return None # 或者处理不匹配的情况
df['product_id_standardized'] = df['product_id'].apply(standardize_sku)
# 将日期标准化为 YYYY-MM-DD 格式
df['order_date_standardized'] = pd.to_datetime(df['order_date'], errors='coerce').dt.strftime('%Y-%m-%d')
print(df)
正则表达式提供定义提取和转换模式的灵活方式,对于处理各种字符串格式非常有用。pd.to_datetime 对于解析不同日期表示形式非常灵活,errors='coerce' 参数会将无法解析的日期转换为 NaT(非时间),可以在后续处理。
异常值可能使统计分析出现偏差并降低模型表现。常见的检测方法包括:
Z-分数: 衡量数据点偏离均值 (μ) 的标准差数量。常用阈值是 ∣Z∣>3。 Z=σx−μ 其中 x 是数据点,μ 是均值,σ 是标准差。
import numpy as np
data = np.array([10, 12, 11, 13, 10, 12, 100, 11, 14])
mean = np.mean(data)
std_dev = np.std(data)
z_scores = (data - mean) / std_dev
print(f"Z-分数: {z_scores}")
outlier_indices = np.where(np.abs(z_scores) > 3)
print(f"异常值索引 (Z > 3): {outlier_indices[0]}")
# 输出:异常值索引 (Z > 3): [6]
四分位距 (IQR): 比 Z-分数对极端值不那么敏感。异常值通常定义为低于 Q1−1.5×IQR 或高于 Q3+1.5×IQR 的点。
q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr
outlier_indices_iqr = np.where((data < lower_bound) | (data > upper_bound))
print(f"异常值索引 (IQR 方法): {outlier_indices_iqr[0]}")
# 输出:异常值索引 (IQR 方法): [6]
可视化: 箱线图直观地显示 IQR 并识别超出常规范围的点。
显示样本数据分布的箱线图。100处的点被清楚地识别为异常值,远高于上须线。
处理策略: 一旦识别,异常值并非总是被移除。请考虑: * 移除: 如果异常值被确认为错误(例如,数据录入错误),则适用。请谨慎,因为移除真实的极端值可能会使结果出现偏差。 * 截顶/温瑟化: 将极端值限制在某个百分位数(例如,将所有高于第99百分位数的值替换为第99百分位数的值)。 * 转换: 应用数学转换(例如,对数、平方根)有时可以降低异常值引起的偏度,使数据更适合某些模型。 * 模型选择: 某些模型(如基于树的方法)本身对异常值不那么敏感,而其他模型(如线性回归)则不然。
对于大型或持续项目,定义明确的数据验证规则可以主动捕获错误。您可以编写自定义 Python 函数或使用 Pandera 或 Great Expectations 等库。
# 简单的自定义验证函数
def validate_order_dates(df, signup_col='signup_date', order_col='order_date'):
"""检查 order_date 是否在 signup_date 之后。"""
invalid_orders = df[pd.to_datetime(df[order_col]) < pd.to_datetime(df[signup_col])]
if not invalid_orders.empty:
print(f"Warning: Found {len(invalid_orders)} records where order date is before signup date.")
# 可能会标记或筛选这些行
return invalid_orders
return pd.DataFrame() # 如果有效,返回空DataFrame
# 使用示例(假设df包含'signup_date'和'order_date'列)
# invalid_df = validate_order_dates(df.copy())
使用 value_counts() 识别变体,并使用 map() 或 replace() 整合它们。
data = {'country': ['USA', 'U.S.A.', 'Canada', 'United States', 'Mexico', 'CAN']}
df_country = pd.DataFrame(data)
print("原始值计数:")
print(df_country['country'].value_counts())
# 定义整合映射
country_map = {
'U.S.A.': 'USA',
'United States': 'USA',
'CAN': 'Canada'
}
df_country['country_standardized'] = df_country['country'].replace(country_map)
print("\n标准化后值计数:")
print(df_country['country_standardized'].value_counts())
虽然这些技术提供有效工具,但自动清洗可能存在风险。理解数据的背景和来源(专业知识)非常重要。一个明显的异常值可能是一个真实且重要的数据点。不一致的类别可能代表有意义的区别。始终将自动化技术与批判性思维结合,并在可能的情况下,咨询相关专家。
清洗数据通常是一个迭代过程。在应用这些高级技术后,您将重新审视诸如处理缺失值(下一节介绍)等步骤并执行转换,这可能会暴露出需要进一步完善的新问题。投入时间进行全面数据清洗,为可靠的分析和有效的机器学习模型奠定坚实基础。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造