Pandas-数据查看与质量检查

发布于:2025-07-13 ⋅ 阅读:(21) ⋅ 点赞:(0)

数据分析流程中,拿到数据后的第一步不是急于建模或可视化,而是全面了解数据——包括数据规模、结构、取值分布以及潜在的质量问题。Pandas作为数据处理的利器,提供了一系列简洁高效的工具,帮助我们快速完成数据查看与质量检查。

一、数据查看:快速掌握数据概况

数据查看的核心目标是回答“数据是什么样的”,包括样本量、特征数、数据类型、取值范围等基础信息。Pandas的几个核心函数可以帮我们快速建立对数据的认知。

1. 整体概览:shape与info()

import pandas as pd
import numpy as np

# 读取示例数据(假设为某电商用户行为数据)
df = pd.read_csv('user_behavior.csv')

# 查看数据规模(行数×列数)
print(f"数据形状:{df.shape}")  # 输出:数据形状:(10000, 8)

# 查看详细信息(数据类型、非空值数量)
df.info()

info()的输出包含关键信息:

  • 每列的名称、数据类型(dtype
  • 非空值数量(可快速判断是否存在缺失值)
  • 内存占用(帮助评估数据规模)

例如,若某列dtype显示为object但实际应为日期,或某列非空值远少于总行数,这些都是需要进一步处理的信号。

2. 数值特征预览:describe()

对于数值型列(int/float),describe()函数提供了基本统计量,帮助快速判断数据分布:

# 查看数值列的统计摘要
df.describe()

输出包含:

  • 计数(count)、均值(mean)、标准差(std
  • 最小值(min)、四分位数(25%/50%/75%)、最大值(max

通过这些指标可初步识别异常值(如最大值远大于75%分位数)或分布偏态(如均值远大于中位数)。

3. 随机抽样:head()与sample()

查看前几行或随机样本,直观感受数据内容:

# 查看前5行(默认)
df.head()

# 查看后10行
df.tail(10)

# 随机抽取5行(避免数据排序导致的偏差)
df.sample(5)

这一步能发现明显的数据错误,例如:

  • 日期列格式混乱(如同时存在2023/1/101-01-2023
  • 分类列存在拼写错误(如"男""男性"同时出现)

二、数据质量检查:识别与处理问题

数据质量直接决定分析结果的可靠性,常见问题包括缺失值、异常值、重复数据和数据类型错误,Pandas提供了针对性的检测与处理工具。

1. 缺失值检查与处理

缺失值是最常见的数据质量问题,需先明确缺失比例和模式:

# 计算每列缺失值数量及比例
missing_count = df.isnull().sum()
missing_ratio = (missing_count / len(df)).round(3)
missing_df = pd.DataFrame({
    '缺失值数量': missing_count,
    '缺失比例': missing_ratio
})
print(missing_df[missing_df['缺失值数量'] > 0])  # 只显示有缺失的列
处理策略:
  • 删除:缺失比例极高(如>80%)或对分析无影响的列:

    df = df.drop(columns=['irrelevant_col'])  # 删除整列
    

    缺失行较少时可删除行:

    df = df.dropna(subset=['critical_col'])  # 只删除关键列缺失的行
    
  • 填充:根据列类型选择填充方式:

    # 数值列:用均值/中位数填充(中位数更抗异常值)
    df['amount'] = df['amount'].fillna(df['amount'].median())
    
    # 分类列:用众数或特殊值(如"未知")填充
    df['category'] = df['category'].fillna(df['category'].mode()[0])
    
    # 日期列:用前后值插值
    df['date'] = df['date'].fillna(method='ffill')  # 向前填充(用上一行值)
    

2. 异常值检测与处理

异常值(离群点)可能扭曲统计结果,需结合业务逻辑判断:

# 方法1:基于标准差(适用于近似正态分布的数据)
def detect_outliers_std(col, n_std=3):
    mean = col.mean()
    std = col.std()
    lower = mean - n_std * std
    upper = mean + n_std * std
    return (col < lower) | (col > upper)

# 检测数值列的异常值
numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
for col in numeric_cols:
    outliers = detect_outliers_std(df[col])
    print(f"{col}异常值比例:{outliers.mean():.2%}")

# 方法2:基于四分位数(IQR法,适用于偏态分布)
Q1 = df['amount'].quantile(0.25)
Q3 = df['amount'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers_iqr = (df['amount'] < lower_bound) | (df['amount'] > upper_bound)
处理策略:
  • 截断:将异常值限制在合理范围(如用上下边界替换)
    df['amount'] = df['amount'].clip(lower_bound, upper_bound)
    
  • 标记:不删除异常值,而是新增列标记供后续分析
    df['is_outlier'] = outliers_iqr
    

3. 重复数据检查与处理

重复数据可能导致分析结果被高估,需检测并去重:

# 检查重复行数量
duplicate_count = df.duplicated().sum()
print(f"重复行数量:{duplicate_count}")

# 查看重复样本
if duplicate_count > 0:
    print(df[df.duplicated(keep=False)].sort_values(by=df.columns.tolist()))

# 删除重复行(保留第一行)
df = df.drop_duplicates(keep='first')

注意:重复行可能是真实数据(如用户重复购买),需结合业务逻辑判断是否去重。

4. 数据类型错误处理

数据类型错误会导致分析函数失效(如对字符串列计算均值),需针对性转换:

# 1. 字符串转日期(关键操作,否则无法按时间分组)
df['order_date'] = pd.to_datetime(df['order_date'], errors='coerce')
# errors='coerce'将无效格式转为NaT(缺失日期)

# 2. 数值型字符串转数值(如"100"→100)
df['price'] = pd.to_numeric(df['price'], errors='coerce')

# 3. 分类列优化(减少内存占用,便于后续分析)
df['gender'] = df['gender'].astype('category')

三、高级检查:一致性与逻辑性验证

除了基础问题,还需验证数据的业务逻辑性,例如:

  • 订单金额不能为负
  • 开始日期不能晚于结束日期
# 检查金额合理性
invalid_amount = df[df['amount'] < 0]
if not invalid_amount.empty:
    print(f"发现{len(invalid_amount)}条金额为负的记录")
    df['amount'] = df['amount'].clip(lower=0)  # 修正为0

# 检查日期逻辑
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])
invalid_dates = df[df['start_date'] > df['end_date']]
if not invalid_dates.empty:
    print(f"发现{len(invalid_dates)}条开始日期晚于结束日期的记录")
    # 交换错误的日期
    mask = df['start_date'] > df['end_date']
    df.loc[mask, ['start_date', 'end_date']] = df.loc[mask, ['end_date', 'start_date']].values

四、实战案例:完整数据质量检查流程

def data_quality_check(df):
    """数据质量检查与清洗函数"""
    print("=== 数据概览 ===")
    print(f"形状:{df.shape}")
    df.info()
    
    print("\n=== 缺失值检查 ===")
    missing = df.isnull().sum()
    missing = missing[missing > 0]
    if not missing.empty:
        print(missing)
        # 处理策略:数值列填充中位数,分类列填充众数
        for col in missing.index:
            if pd.api.types.is_numeric_dtype(df[col]):
                df[col] = df[col].fillna(df[col].median())
            else:
                df[col] = df[col].fillna(df[col].mode()[0])
        print("缺失值已处理")
    else:
        print("无缺失值")
    
    print("\n=== 重复数据检查 ===")
    duplicates = df.duplicated().sum()
    if duplicates > 0:
        df = df.drop_duplicates()
        print(f"删除{duplicates}条重复行,剩余{len(df)}行")
    else:
        print("无重复数据")
    
    print("\n=== 异常值检查 ===")
    numeric_cols = df.select_dtypes(include=['number']).columns
    for col in numeric_cols:
        Q1 = df[col].quantile(0.25)
        Q3 = df[col].quantile(0.75)
        IQR = Q3 - Q1
        outliers = (df[col] < (Q1 - 1.5 * IQR)) | (df[col] > (Q3 + 1.5 * IQR))
        if outliers.sum() > 0:
            print(f"{col}存在{outliers.sum()}个异常值,已截断至合理范围")
            df[col] = df[col].clip(Q1 - 1.5 * IQR, Q3 + 1.5 * IQR)
    
    print("\n=== 数据类型修正 ===")
    # 自动检测并转换日期列
    for col in df.columns:
        if 'date' in col.lower():
            df[col] = pd.to_datetime(df[col], errors='coerce')
    print("数据类型已修正")
    
    return df

# 执行检查与清洗
clean_df = data_quality_check(df)

总结:数据质量检查的核心原则

  1. 全面扫描:结合统计指标与样本查看,不遗漏任何列。
  2. 区别对待:根据列的类型(数值/分类/日期)选择合适的检查方法。
  3. 业务导向:异常值和缺失值的处理需符合业务逻辑,而非机械套用公式。
  4. 可复现性:将检查与清洗步骤封装为函数,确保流程可重复、可追溯。

That’s all, thanks for reading~~
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~


网站公告

今日签到

点亮在社区的每一天
去签到