一周学会Pandas2之Python数据处理与分析-Pandas2数据清洗与准备

锋哥原创的Pandas2 Python数据处理与分析 视频教程:  

2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili

数据清洗是数据分析的一个重要步骤,关系到数据的质量,而数据的质量又关系到数据分析的效果。数据清洗一般包括缺失值填充、冗余数据删除、数据格式化、异常值处理、逻辑错误数据检测、数据一致性校验、重复值过滤、数据质量评估等。Pandas提供了一系列操作方法帮助我们轻松完成这些操作。

缺省值处理

1,检测缺省值

isna() 或 isnull(),检测缺失值 (NaN, None, NaT),返回布尔型 DataFrame/Series

示例:

import pandas as pd
import numpy as np
​
df = pd.DataFrame({
    'A': [1, np.nan, 3],
    'B': ['x', None, 'z'],
    'C': [pd.NaT, pd.Timestamp('2023'), None]
})
​
# 检测所有缺失值
print(df.isna())

notna() 或 notnull(),检测非缺失值,与 isna() 结果相反

统计缺失值数量

按列统计

print(df.isna().sum())

总体统计

print(df.isna().sum().sum())  # 总缺失值数量

2,删除缺失值

在 Pandas 中,dropna() 是处理缺失值的核心方法,用于删除包含缺失值(NaNNoneNaT)的行或列。以下是详细用法总结,结合场景和代码示例说明:

基本语法:

DataFrame.dropna(
    axis=0,          # 删除方向:0 或 'index'(行),1 或 'columns'(列)
    how='any',        # 删除条件:'any'(存在缺失即删),'all'(全为缺失才删)
    thresh=None,      # 保留非缺失值数量 ≥ thresh 的行/列
    subset=None,      # 指定检查缺失值的列/行子集
    inplace=False     # 是否原地修改(不返回新对象)
)

我们看一个示例:

import pandas as pd
import numpy as np
​
data = {
    'A': [1, np.nan, 3, 4],
    'B': [np.nan, 5, None, 7],
    'C': ['x', 'y', np.nan, 'z']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)

删除缺失值行,保留非缺失值数量大于等于2.

df.dropna(thresh=2)

3,填充缺失值

缺失值填充,我们用fillna()方法,前面已经介绍过。

处理重复值

检测重复行

在 Pandas 中,duplicated() 是用于检测 DataFrame 或 Series 中重复行或元素的核心方法。它返回一个布尔值序列,标记重复项(True 表示重复)。以下是详细用法说明,结合代码示例和场景分析:

基本语法:

DataFrame.duplicated(
    subset=None,    # 指定判断重复的列(默认所有列)
    keep='first',   # 标记策略:'first'(默认保留第一个),'last'(保留最后一个),False(全标记为重复)
    inplace=False   # 是否原地修改(无返回值,仅适用于某些操作,通常不用于此方法)
)

示例:

数据准备:

import pandas as pd
​
data = {
    'ID': [101, 102, 103, 101, 102],
    'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
    'Score': [85, 90, 95, 85, 90]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)

检测所有列完全重复的行。

df.duplicated()

删除重复行

在 Pandas 中,drop_duplicates() 是用于删除 DataFrame 或 Series 中重复行的核心方法。它基于用户定义的规则(如保留首个或末个重复项、指定判断重复的列等)清理数据。以下是详细用法说明,结合代码示例和场景分析:

基本语法:

DataFrame.drop_duplicates(
    subset=None,        # 指定判断重复的列(默认所有列)
    keep='first',       # 保留策略:'first'(保留第一个重复项)、'last'(保留最后一个)、False(删除所有重复项)
    inplace=False,      # 是否直接修改原对象(不返回新对象)
    ignore_index=False  # 是否重置删除后的索引(默认保持原索引)
)

示例:

df.drop_duplicates()

数据类型转换

数据类型转换用astype()和to_numeric()这些方法,前面已经介绍过。

字符串处理

核心方法(通过 .str 访问器):

  • 清洗与转换

    df['列名'].str.strip()               # 去除两端空格
    df['列名'].str.lower()               # 转为小写
    df['列名'].str.upper()               # 转为大写
    df['列名'].str.replace('old', 'new') # 替换字符
  • 分割与合并

    df['列名'].str.split(',', expand=True)  # 分割为多列(返回 DataFrame)
    df['合并列'] = df['列1'].str.cat(df['列2'], sep='-')  # 合并两列
  • 正则表达式

    df['列名'].str.extract(r'(\d+)')        # 提取数字
    df['列名'].str.contains(r'^A', na=False)  # 检查是否以 A 开头(处理缺失值)

数据合并

前面已经讲过。

数据筛选

条件筛选

  • 多条件组合

    df[(df['A'] > 10) & (df['B'] == 'X')]   # 且(and)
    df[(df['A'] > 10) | (df['B'] == 'X')]   # 或(or)
    df[~df['B'].isin(['X', 'Y'])]           # 非(not in)
  • query 方法

    df.query('A > 10 and B == "X"')  # 更简洁的条件表达式

按位置筛选

  • loc 和 iloc

    df.loc[df['A'] > 10, ['B', 'C']]  # 筛选行,选择 B、C 列
    df.iloc[0:5, [1, 2]]             # 前5行,第2、3列

数据分组与聚合

  • 单列聚合

    df.groupby('分组列')['数值列'].agg(['sum', 'mean', 'max'])
  • 多列不同聚合方式

    df.groupby('分组列').agg({
        '数值列1': 'sum',
        '数值列2': lambda x: x.mean() * 100
    })

异常值处理

统计方法识别

  • Z-Score 法Z-Score(标准分数)是一种统计学方法,用于衡量数据点与数据集均值的偏离程度,以标准差为单位。它在数据预处理(如异常值检测、数据标准化)中广泛应用,尤其在机器学习和数据分析中常用于数据规范化。

    z_scores = (df['列名'] - df['列名'].mean()) / df['列名'].std()
    df = df[z_scores.abs() < 3]  # 删除 Z 值绝对值大于3的异常值
  • IQR 法IQR 法(四分位距法,Interquartile Range)是一种基于数据分位数的异常值检测方法,适用于识别数据中的极端值,尤其对非正态分布数据(如偏态分布)具有更强的鲁棒性。它通过计算数据的四分位距(IQR)来确定正常值的范围,超出此范围的数据点被视为异常值。

    Q1 = df['列名'].quantile(0.25)
    Q3 = df['列名'].quantile(0.75)
    IQR = Q3 - Q1
    df = df[(df['列名'] >= Q1 - 1.5*IQR) & (df['列名'] <= Q3 + 1.5*IQR)]

替换异常值

df.loc[df['列名'] > 1000, '列名'] = 1000  # 将超过1000的值截断为1000

列操作和重命名

添加新列

df['新列'] = df['列1'] + df['列2']
df['新列'] = np.where(df['列名'] > 100, '高', '低')  # 条件赋值

删除列

df.drop(['列1', '列2'], axis=1, inplace=True)

重命名

df.rename(columns={'旧列名': '新列名'}, inplace=True)

索引操作

  • 设置索引

    df.set_index('日期列', inplace=True)  # 将日期列设为索引
  • 重置索引

    df.reset_index(drop=True, inplace=True)  # 删除原索引

完整数据清洗示例

test.data.csv

ID,Name,Age,Gender,Department,Salary,HireDate
1,Alice,28,F,HR,55000,2023-01-15
2,Bob,32,M,IT,65000,2023-02-20
3,Charlie,,M,IT,,2023-03-05
4,David,45,M,Finance,75000,2023-04-10
5,Eve,22,F,HR,48000,2023-05-12
6,Frank,38,M,IT,82000,2023-06-18
7,Grace,29,F,Marketing,63000,2023-07-25
8,Heidi,35,F,Finance,,2023-08-30
9,Ivan,41,M,IT,71000,2023-09-14
10,Judy,33,F,HR,59000,2023-10-22
11,Alex,25,M,IT,150000,2023-11-05
12,Sam,27,F,Marketing,18000,2023-12-10    

测试代码:

import pandas as pd
​
​
def load_data(file_path):
    """加载 CSV 数据"""
    try:
        return pd.read_csv(file_path)
    except FileNotFoundError:
        print(f"错误: 文件 '{file_path}' 不存在")
        return None
​
​
def clean_data(df):
    """清洗数据"""
    if df is None:
        return None
​
    # 处理缺失值
    print("处理缺失值...")
    df = df.dropna(subset=['Name'])  # 删除 Name 列中的缺失值
    df['Age'] = df['Age'].fillna(df['Age'].median())  # 用中位数填充 Age 列
    df['Salary'] = df['Salary'].fillna(df['Salary'].mean())  # 用均值填充 Salary 列
​
    # 处理重复值
    print("处理重复值...")
    duplicates = df.duplicated().sum()
    if duplicates > 0:
        df = df.drop_duplicates()
        print(f"已删除 {duplicates} 个重复行")
​
    # 处理异常值
    print("处理异常值...")
    Q1 = df['Salary'].quantile(0.25)
    Q3 = df['Salary'].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    df = df[(df['Salary'] >= lower_bound) & (df['Salary'] <= upper_bound)]
    # 数据类型转换
    print("数据类型转换...")
    df['HireDate'] = pd.to_datetime(df['HireDate'])
​
    return df
​
​
def main():
    input_file = 'test_data.csv'
    output_file = 'cleaned_data.csv'
​
    # 加载数据
    df = load_data(input_file)
    if df is None:
        return
​
    print("原始数据基本信息:")
    df.info()
​
    # 数据清洗
    cleaned_df = clean_data(df)
​
    # 保存结果
    if cleaned_df is not None:
        cleaned_df.to_csv(output_file, index=False)
        print(f"清洗后的数据已保存到 {output_file}")
        print("清洗后数据基本信息:")
        cleaned_df.info()
​
​
if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值