本文目录导读:

我来介绍几个使用Pandas进行数据格式清洗的典型案例:
案例1:处理缺失值
import pandas as pd
import numpy as np
# 创建示例数据
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '赵六', None],
'年龄': [25, None, 30, 35, 28],
'工资': [8000, 9000, None, 11000, 9500],
'入职日期': ['2023-01-15', '2023/02/20', '2023-03-25', '2023-04-30', '20230505']
})
print("原始数据:")
print(df)
print("\n")
# 1. 检查缺失值
print("缺失值统计:")
print(df.isnull().sum())
# 2. 填充缺失值
# 用均值填充年龄
df['年龄'].fillna(df['年龄'].mean(), inplace=True)
# 用前向填充法填充工资
df['工资'].fillna(method='ffill', inplace=True)
# 删除包含缺失值的行
df.dropna(subset=['姓名'], inplace=True)
print("\n清洗后的数据:")
print(df)
案例2:统一日期格式
import pandas as pd
# 创建包含多种日期格式的数据
df = pd.DataFrame({
'日期': ['2023-01-15', '2023/02/20', '2023.03.25', '20230430',
'2023-05-15 14:30:00', '06/15/2023', '15-06-2023'],
'销售额': [1000, 2000, 1500, 3000, 2500, 1800, 2200]
})
print("原始日期数据:")
print(df)
# 统一日期格式为YYYY-MM-DD
def clean_date(date_str):
try:
# 尝试多种常见格式
date_formats = [
'%Y-%m-%d', # 2023-01-15
'%Y/%m/%d', # 2023/02/20
'%Y.%m.%d', # 2023.03.25
'%Y%m%d', # 20230430
'%Y-%m-%d %H:%M:%S', # 2023-05-15 14:30:00
'%m/%d/%Y', # 06/15/2023
'%d-%m-%Y' # 15-06-2023
]
for fmt in date_formats:
try:
return pd.to_datetime(date_str, format=fmt)
except:
continue
# 如果都不匹配,尝试自动解析
return pd.to_datetime(date_str)
except:
return pd.NaT
df['清洗后日期'] = df['日期'].apply(clean_date)
print("\n清洗后的日期:")
print(df[['日期', '清洗后日期']])
案例3:文本数据清洗
import pandas as pd
# 创建包含脏数据的文本数据集
df = pd.DataFrame({
'产品名称': [' 苹果iPhone 14 ', '华为 Mate 60 ', ' 小米14 Pro ',
'OPPO Find X6', ' VIVO X90 '],
'价格': ['¥5999', '¥6999元', '4,999元', '¥4499.00', '3999'],
'库存': ['100件', '50 件', '80件', '200件', '150件']
})
print("原始数据:")
print(df)
# 文本清洗函数
def clean_text_data(df):
# 1. 去除空格
df['产品名称'] = df['产品名称'].str.strip()
# 2. 清洗价格列
df['价格'] = df['价格'].str.replace('¥', '', regex=False)
df['价格'] = df['价格'].str.replace('元', '', regex=False)
df['价格'] = df['价格'].str.replace(',', '', regex=False)
df['价格'] = df['价格'].str.strip()
df['价格'] = pd.to_numeric(df['价格'], errors='coerce')
# 3. 清洗库存列
df['库存'] = df['库存'].str.replace('件', '', regex=False)
df['库存'] = df['库存'].str.strip()
df['库存'] = pd.to_numeric(df['库存'], errors='coerce')
return df
df_cleaned = clean_text_data(df.copy())
print("\n清洗后的数据:")
print(df_cleaned)
print("\n数据类型:")
print(df_cleaned.dtypes)
案例4:复杂数据清洗综合案例
import pandas as pd
import numpy as np
# 创建更复杂的脏数据集
df = pd.DataFrame({
'用户ID': ['U001', 'U002', 'U003', 'U004', 'U005', 'U006'],
'姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八'],
'邮箱': ['zhangsan@qq.com', 'lisi@163.com', 'wangwu@gmail',
'zhaoliu@.com', 'sunqi@qq.com', 'zhouba@qq.com'],
'电话': ['13800138001', '13900139002', '14000140003',
'14100141004', '14200142005', '14300143006'],
'年龄': ['25', '30岁', '35', '四十', '28', '33'],
'收入': ['8000.50', '9,000.00', '10000', '11000元', '12000', 'NaN'],
'状态': ['活跃', '不活跃', '活跃', 'active', 'inactive', 'ACTIVE']
})
print("原始数据:")
print(df)
print("\n数据类型:")
print(df.dtypes)
def comprehensive_clean(df):
cleaned_df = df.copy()
# 1. 标准化邮箱
def clean_email(email):
if pd.isna(email):
return None
email = str(email).strip().lower()
# 补全邮箱后缀
if '@' not in email:
return None
parts = email.split('@')
if not parts[0] or not parts[1]:
return None
# 确保有顶级域名
if '.' not in parts[1]:
return None
return email
cleaned_df['邮箱'] = cleaned_df['邮箱'].apply(clean_email)
# 2. 标准化电话
def clean_phone(phone):
if pd.isna(phone):
return None
phone = str(phone).strip()
# 只保留数字
phone = ''.join(filter(str.isdigit, phone))
if len(phone) == 11 and phone.startswith('1'):
return phone
return None
cleaned_df['电话'] = cleaned_df['电话'].apply(clean_phone)
# 3. 标准化年龄
def clean_age(age):
if pd.isna(age):
return None
age = str(age).strip()
# 移除"岁"等文字
age = age.replace('岁', '').strip()
try:
age_num = int(age)
if 0 < age_num < 150:
return age_num
except:
return None
return None
cleaned_df['年龄'] = cleaned_df['年龄'].apply(clean_age)
# 4. 标准化收入
def clean_income(income):
if pd.isna(income) or str(income).lower() == 'nan':
return None
income = str(income).strip()
# 移除¥、元等符号
income = income.replace('¥', '').replace('元', '').replace(',', '')
try:
income_num = float(income)
if income_num > 0:
return income_num
except:
return None
return None
cleaned_df['收入'] = cleaned_df['收入'].apply(clean_income)
# 5. 标准化状态
def clean_status(status):
if pd.isna(status):
return '未知'
status = str(status).strip().lower()
status_map = {
'active': '活跃', 'inactive': '不活跃', 'active!': '活跃',
'活跃': '活跃', '不活跃': '不活跃'
}
return status_map.get(status, '未知')
cleaned_df['状态'] = cleaned_df['状态'].apply(clean_status)
return cleaned_df
df_cleaned = comprehensive_clean(df)
print("\n清洗后的数据:")
print(df_cleaned)
print("\n清洗后数据类型:")
print(df_cleaned.dtypes)
# 保存清洗后的数据
df_cleaned.to_csv('cleaned_data.csv', index=False, encoding='utf-8-sig')
print("\n数据已保存到 'cleaned_data.csv'")
常用数据清洗技巧总结
import pandas as pd
# 1. 数据类型转换
def type_conversion_tips():
df = pd.DataFrame({'col1': ['1', '2', '3'], 'col2': ['2023-01-01', '2023-01-02', '2023-01-03']})
# 转换为数值
df['col1'] = pd.to_numeric(df['col1'], errors='coerce')
# 转换为日期
df['col2'] = pd.to_datetime(df['col2'])
return df
# 2. 处理重复值
def duplicate_handling(df):
# 检查重复
print(f"重复行数: {df.duplicated().sum()}")
# 删除重复
df_clean = df.drop_duplicates()
# 基于特定列删除重复
df_clean2 = df.drop_duplicates(subset=['列名1', '列名2'])
return df_clean
# 3. 数据标准化
def standardization_tips():
# 字符串标准化
df = pd.DataFrame({'text': [' Hello ', 'World ', ' Python ']})
df['text'] = df['text'].str.strip().str.lower() # 去除空格并转为小写
# 分类数据标准化
status_map = {'Y': '是', 'N': '否', 'yes': '是', 'no': '否'}
df['status'] = df['status'].map(status_map)
return df
# 4. 异常值处理
def outlier_handling(df, column, method='iqr'):
if method == '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] = df[column].clip(lower=lower_bound, upper=upper_bound)
return df
这些案例涵盖了大多数常见的数据清洗场景,根据实际需求,你可以组合使用这些技巧来处理更复杂的数据清洗任务。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播