您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Python清洗数据的方法是什么
## 引言
在数据分析和机器学习项目中,数据清洗(Data Cleaning)是至关重要的一环。据统计,数据科学家80%的时间都花在数据清洗和准备上。Python凭借其丰富的生态系统和强大的库支持,成为数据清洗的首选工具。本文将系统介绍Python中常用的数据清洗方法,涵盖从基础到进阶的完整流程。
## 一、数据清洗概述
### 1.1 什么是数据清洗
数据清洗是指识别并纠正(或删除)数据集中的不准确、不完整、不合理或重复的记录的过程。主要包括:
- 处理缺失值
- 处理异常值
- 数据格式标准化
- 处理重复数据
- 数据转换
### 1.2 为什么需要数据清洗
- 提高数据质量
- 确保分析结果准确
- 提升模型性能
- 符合数据规范要求
## 二、Python数据清洗核心库
### 2.1 Pandas
```python
import pandas as pd
Pandas是Python数据处理的核心库,提供DataFrame数据结构。
import numpy as np
用于数值计算,特别是处理缺失值。
re
:正则表达式datetime
:日期处理scipy.stats
:统计处理# 从CSV加载
df = pd.read_csv('data.csv')
# 从Excel加载
df = pd.read_excel('data.xlsx')
# 从数据库加载
import sqlite3
conn = sqlite3.connect('database.db')
df = pd.read_sql_query("SELECT * FROM table", conn)
# 查看前5行
df.head()
# 数据基本信息
df.info()
# 统计描述
df.describe()
# 查看列名
df.columns
# 形状(行数,列数)
df.shape
# 每列缺失值数量
df.isnull().sum()
# 缺失值比例
df.isnull().mean()
# 可视化缺失值
import seaborn as sns
sns.heatmap(df.isnull(), cbar=False)
# 删除含有缺失值的行
df.dropna(axis=0)
# 删除含有缺失值的列
df.dropna(axis=1)
# 删除全为NA的行
df.dropna(how='all')
# 删除NA超过阈值的行
df.dropna(thresh=len(df.columns)-2) # 允许最多2个NA
# 用固定值填充
df.fillna(0)
# 前向填充
df.fillna(method='ffill')
# 后向填充
df.fillna(method='bfill')
# 用均值/中位数填充
df['column'].fillna(df['column'].mean(), inplace=True)
df['column'].fillna(df['column'].median(), inplace=True)
# 用众数填充
df['column'].fillna(df['column'].mode()[0], inplace=True)
# 分组填充
df['column'] = df.groupby('group_column')['column'].transform(
lambda x: x.fillna(x.mean()))
# 线性插值
df['column'].interpolate()
# 时间序列插值
df['column'].interpolate(method='time')
使用KNN、随机森林等算法预测缺失值:
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
df_filled = imputer.fit_transform(df)
# 查看数值列的五数概括
df.describe()
# 定义IQR范围
Q1 = df['column'].quantile(0.25)
Q3 = df['column'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5*IQR
upper_bound = Q3 + 1.5*IQR
# 箱线图
df['column'].plot(kind='box')
# 直方图
df['column'].plot(kind='hist', bins=50)
# 散点图
df.plot(kind='scatter', x='col1', y='col2')
from scipy import stats
z_scores = stats.zscore(df['column'])
abs_z_scores = np.abs(z_scores)
outliers = (abs_z_scores > 3)
使用DBSCAN等聚类算法识别离群点。
df = df[(df['column'] >= lower_bound) & (df['column'] <= upper_bound)]
# 用边界值替换
df['column'] = np.where(df['column'] > upper_bound, upper_bound,
np.where(df['column'] < lower_bound, lower_bound, df['column']))
# 用中位数替换
median = df['column'].median()
df['column'] = np.where(outliers, median, df['column'])
bins = [0, 25, 50, 75, 100]
labels = ['low', 'medium', 'high', 'very_high']
df['column_binned'] = pd.cut(df['column'], bins=bins, labels=labels)
# 对数变换
df['column_log'] = np.log1p(df['column'])
# 标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df['column_scaled'] = scaler.fit_transform(df[['column']])
# 完全重复的行
df.duplicated()
# 基于某些列的重复
df.duplicated(subset=['col1', 'col2'])
# 重复行计数
df.duplicated().sum()
# 删除完全重复的行
df.drop_duplicates(inplace=True)
# 基于某些列删除重复
df.drop_duplicates(subset=['col1', 'col2'], keep='first')
# 保留最后出现的重复项
df.drop_duplicates(keep='last')
# 删除所有重复项
df.drop_duplicates(keep=False)
df.dtypes
# 转换为数值
df['column'] = pd.to_numeric(df['column'], errors='coerce')
# 转换为日期
df['date_column'] = pd.to_datetime(df['date_column'], format='%Y-%m-%d')
# 转换为分类
df['category_column'] = df['category_column'].astype('category')
# 转换为字符串
df['str_column'] = df['str_column'].astype(str)
# 去除空格
df['text_column'] = df['text_column'].str.strip()
# 大小写转换
df['text_column'] = df['text_column'].str.lower()
# 去除标点
import string
df['text_column'] = df['text_column'].str.translate(
str.maketrans('', '', string.punctuation))
import re
# 提取数字
df['numbers'] = df['text_column'].str.extract('(\d+)')
# 替换模式
df['clean_text'] = df['text_column'].str.replace(r'\b[A-Z]{2,}\b', '', regex=True)
# 复杂模式匹配
phone_pattern = r'(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}'
df['phones'] = df['text_column'].str.findall(phone_pattern)
df['date'] = pd.to_datetime(df['date_str'], format='%m/%d/%Y')
# 自动推断格式
df['date'] = pd.to_datetime(df['date_str'], infer_datetime_format=True)
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day
df['weekday'] = df['date'].dt.weekday
df['is_weekend'] = df['date'].dt.weekday >= 5
# 日期差
df['days_diff'] = (df['date1'] - df['date2']).dt.days
# 日期偏移
from pandas.tseries.offsets import Day, MonthEnd
df['next_month'] = df['date'] + MonthEnd(1)
# 标签编码
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['encoded'] = le.fit_transform(df['category_column'])
# 独热编码
pd.get_dummies(df, columns=['category_column'])
# 有序类别编码
size_order = ['S', 'M', 'L', 'XL']
df['size_code'] = df['size'].astype(
pd.CategoricalDtype(categories=size_order, ordered=True)).cat.codes
# 低频类别合并
value_counts = df['category_column'].value_counts()
to_merge = value_counts[value_counts < 10].index
df['category_column'] = df['category_column'].replace(to_merge, 'Other')
# 等宽分箱
df['bin'] = pd.cut(df['value'], bins=5)
# 等频分箱
df['bin'] = pd.qcut(df['value'], q=5)
# 自定义分箱
bins = [0, 18, 35, 60, 100]
labels = ['child', 'young', 'adult', 'senior']
df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels)
# Min-Max标准化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
df['scaled'] = scaler.fit_transform(df[['value']])
# Z-score标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df['standardized'] = scaler.fit_transform(df[['value']])
# 数值特征相乘
df['feature_cross'] = df['col1'] * df['col2']
# 类别特征组合
df['combined_category'] = df['category1'] + '_' + df['category2']
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
num_pipeline = Pipeline([
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
df_num = num_pipeline.fit_transform(df.select_dtypes(include=[np.number]))
from sklearn.base import BaseEstimator, TransformerMixin
class CustomCleaner(BaseEstimator, TransformerMixin):
def __init__(self, columns=None):
self.columns = columns
def fit(self, X, y=None):
return self
def transform(self, X):
X = X.copy()
if self.columns:
for col in self.columns:
X[col] = X[col].str.lower().str.strip()
return X
import great_expectations as ge
df_ge = ge.from_pandas(df)
df_ge.expect_column_values_to_not_be_null('important_column')
df_ge.expect_column_values_to_be_between('age', min_value=0, max_value=120)
def validate_data(df):
errors = []
# 检查缺失值
if df['id'].isnull().any():
errors.append("ID列存在缺失值")
# 检查范围
if (df['age'] < 0).any() or (df['age'] > 120).any():
errors.append("年龄值超出合理范围")
return errors
Python提供了丰富的数据清洗工具和方法,从基础的缺失值处理到高级的特征工程。掌握这些技术可以显著提高数据质量,为后续分析和建模奠定坚实基础。实际项目中,应根据数据特点和业务需求选择合适的清洗策略,并通过自动化流程提高效率。
本文共约4750字,详细介绍了Python数据清洗的完整流程和方法。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。