import pandas as pd
import numpy as np
# 创建示例数据
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 22, 35],
'薪资': [5000, 8000, 4500, 9000],
'部门': ['技术部', '销售部', '技术部', '人事部']
}
df = pd.DataFrame(data)
# 1.1 按单列排序(默认升序)
df_sorted_age = df.sort_values('年龄')
print("按年龄升序排序:")
print(df_sorted_age)
# 1.2 按单列降序排序
df_sorted_salary_desc = df.sort_values('薪资', ascending=False)
print("\n按薪资降序排序:")
print(df_sorted_salary_desc)
# 1.3 按多列排序
df_sorted_multi = df.sort_values(['部门', '薪资'], ascending=[True, False])
print("\n先按部门升序,再按薪资降序:")
print(df_sorted_multi)
# 1.4 排序后重置索引
df_sorted_reset = df.sort_values('年龄').reset_index(drop=True)
print("\n排序后重置索引:")
print(df_sorted_reset)
# 创建包含缺失值的示例数据
df_with_na = pd.DataFrame({
'A': [1, 3, np.nan, 2],
'B': [5, np.nan, 7, 8],
'C': ['X', 'Y', 'X', 'Z']
})
# 2.1 处理缺失值的排序
df_sorted_na_first = df_with_na.sort_values('A', na_position='first')
print("缺失值在前:")
print(df_sorted_na_first)
df_sorted_na_last = df_with_na.sort_values('A', na_position='last')
print("\n缺失值在后:")
print(df_sorted_na_last)
# 2.2 按索引排序
df_shuffled = df.sample(frac=1, random_state=42) # 随机打乱数据
df_sorted_index = df_shuffled.sort_index()
print("\n按索引排序:")
print(df_sorted_index)
# 2.3 使用自定义排序规则
# 创建自定义排序顺序
dept_order = ['人事部', '销售部', '技术部']
df['部门'] = pd.Categorical(df['部门'], categories=dept_order, ordered=True)
df_sorted_custom = df.sort_values('部门')
print("\n按自定义部门顺序排序:")
print(df_sorted_custom)
# 创建包含字符串的数据
str_data = {
'姓名': ['张三 Zhang', '李四-li', '王五 Wang', '赵六_ZHAO'],
'邮箱': ['zhangsan@example.com', 'lisi@test.com', 'wangwu@demo.cn', 'zhaoliu@sample.org'],
'电话': ['138-0013-8000', '13912345678', '130 5555 6666', '137-7777-8888']
}
df_str = pd.DataFrame(str_data)
# 1.1 大小写转换
df_str['姓名_大写'] = df_str['姓名'].str.upper()
df_str['姓名_小写'] = df_str['姓名'].str.lower()
df_str['姓名_首字母大写'] = df_str['姓名'].str.title()
print("字符串大小写转换:")
print(df_str[['姓名', '姓名_大写', '姓名_小写', '姓名_首字母大写']])
# 1.2 去除空白字符
df_str['姓名_去空格'] = df_str['姓名'].str.strip()
df_str['姓名_去左边空格'] = df_str['姓名'].str.lstrip()
df_str['姓名_去右边空格'] = df_str['姓名'].str.rstrip()
# 1.3 字符串替换
df_str['电话_格式化'] = df_str['电话'].str.replace('-', '').str.replace(' ', '')
print("\n电话格式化:")
print(df_str[['电话', '电话_格式化']])
# 1.4 字符串分割
df_str[['姓氏', '名字']] = df_str['姓名'].str.split(' ', expand=True)
print("\n姓名分割:")
print(df_str[['姓名', '姓氏', '名字']])
# 1.5 字符串合并
df_str['全名'] = df_str['姓氏'] + ' ' + df_str['名字'].fillna('')
print("\n姓名合并:")
print(df_str[['姓氏', '名字', '全名']])
# 2.1 字符串提取和匹配
df_str['邮箱域名'] = df_str['邮箱'].str.extract(r'@(.+)')
df_str['是否公司邮箱'] = df_str['邮箱'].str.contains('example|test', case=False)
print("邮箱处理:")
print(df_str[['邮箱', '邮箱域名', '是否公司邮箱']])
# 2.2 字符串长度和计数
df_str['姓名长度'] = df_str['姓名'].str.len()
df_str['空格数量'] = df_str['姓名'].str.count(' ')
print("\n字符串统计:")
print(df_str[['姓名', '姓名长度', '空格数量']])
# 2.3 字符串填充和对齐
df_str['ID_左填充'] = df_str.index.astype(str).str.zfill(3)
df_str['姓名_右对齐'] = df_str['姓名'].str.pad(width=15, side='right', fillchar='-')
print("\n字符串填充:")
print(df_str[['ID_左填充', '姓名', '姓名_右对齐']])
# 2.4 使用正则表达式的高级匹配
df_str['提取数字'] = df_str['电话'].str.extract(r'(\d{3})')
df_str['是否有效邮箱'] = df_str['邮箱'].str.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
print("\n正则表达式匹配:")
print(df_str[['电话', '提取数字', '邮箱', '是否有效邮箱']])
# 创建包含日期时间的数据
date_data = {
'订单ID': ['001', '002', '003', '004'],
'订单日期': ['2023-01-15', '2023-02-20', '2023-03-10', '2023-04-05'],
'发货时间': ['2023-01-16 10:30:00', '2023-02-21 14:45:00',
'2023-03-11 09:15:00', '2023-04-06 16:20:00']
}
df_date = pd.DataFrame(date_data)
# 1.1 转换为日期时间类型
df_date['订单日期'] = pd.to_datetime(df_date['订单日期'])
df_date['发货时间'] = pd.to_datetime(df_date['发货时间'])
print("原始日期数据:")
print(df_date.dtypes)
print(df_date)
# 1.2 提取日期时间组件
df_date['订单年份'] = df_date['订单日期'].dt.year
df_date['订单月份'] = df_date['订单日期'].dt.month
df_date['订单日'] = df_date['订单日期'].dt.day
df_date['星期几'] = df_date['订单日期'].dt.day_name()
df_date['季度'] = df_date['订单日期'].dt.quarter
print("\n日期组件提取:")
print(df_date[['订单日期', '订单年份', '订单月份', '订单日', '星期几', '季度']])
# 1.3 时间组件提取
df_date['小时'] = df_date['发货时间'].dt.hour
df_date['分钟'] = df_date['发货时间'].dt.minute
df_date['是否工作日'] = df_date['发货时间'].dt.weekday < 5
print("\n时间组件提取:")
print(df_date[['发货时间', '小时', '分钟', '是否工作日']])
# 2.1 日期时间计算
df_date['处理时长'] = df_date['发货时间'] - df_date['订单日期']
df_date['处理时长_小时'] = df_date['处理时长'].dt.total_seconds() / 3600
print("日期时间计算:")
print(df_date[['订单日期', '发货时间', '处理时长', '处理时长_小时']])
# 2.2 日期偏移
df_date['预计送达'] = df_date['发货时间'] + pd.Timedelta(days=3)
df_date['下月同日'] = df_date['订单日期'] + pd.DateOffset(months=1)
print("\n日期偏移:")
print(df_date[['发货时间', '预计送达', '订单日期', '下月同日']])
# 2.3 日期范围生成
date_range = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D')
print("\n日期范围:")
print(date_range)
# 2.4 重采样和时间序列分析
# 创建时间序列数据
time_series = pd.DataFrame({
'日期': pd.date_range('2023-01-01', periods=30, freq='D'),
'销售额': np.random.randint(100, 1000, 30)
})
# 按周重采样
weekly_sales = time_series.resample('W', on='日期')['销售额'].sum().reset_index()
print("\n周销售额汇总:")
print(weekly_sales)
# 2.5 日期格式化
df_date['订单日期_str'] = df_date['订单日期'].dt.strftime('%Y年%m月%d日')
df_date['发货时间_str'] = df_date['发货时间'].dt.strftime('%H:%M:%S')
print("\n日期格式化:")
print(df_date[['订单日期', '订单日期_str', '发货时间', '发货时间_str']])
# 创建示例数据
df1 = pd.DataFrame({
'员工ID': ['E001', 'E002', 'E003', 'E004'],
'姓名': ['张三', '李四', '王五', '赵六'],
'部门': ['技术部', '销售部', '技术部', '人事部']
})
df2 = pd.DataFrame({
'员工ID': ['E001', 'E002', 'E005'],
'薪资': [5000, 8000, 6000],
'入职日期': ['2020-01-15', '2019-05-20', '2021-03-10']
})
df3 = pd.DataFrame({
'员工ID': ['E003', 'E004', 'E001'],
'绩效': ['A', 'B', 'A+'],
'奖金': [2000, 1500, 3000]
})
# 1.1 merge合并(类似SQL JOIN)
# 内连接
df_inner = pd.merge(df1, df2, on='员工ID', how='inner')
print("内连接结果:")
print(df_inner)
# 左连接
df_left = pd.merge(df1, df2, on='员工ID', how='left')
print("\n左连接结果:")
print(df_left)
# 外连接
df_outer = pd.merge(df1, df2, on='员工ID', how='outer')
print("\n外连接结果:")
print(df_outer)
# 1.2 多表合并
df_multi = pd.merge(pd.merge(df1, df2, on='员工ID', how='left'),
df3, on='员工ID', how='left')
print("\n多表合并结果:")
print(df_multi)
# 1.3 concat合并(沿轴拼接)
df_concat_rows = pd.concat([df1, df2], axis=0, ignore_index=True)
print("\n纵向拼接结果:")
print(df_concat_rows)
df_concat_cols = pd.concat([df1, df3[['绩效', '奖金']]], axis=1)
print("\n横向拼接结果:")
print(df_concat_cols)
# 2.1 按条件拆分
# 创建示例数据
sales_data = pd.DataFrame({
'销售员': ['张三', '李四', '王五', '赵六', '张三', '李四'],
'产品': ['A', 'B', 'A', 'C', 'B', 'A'],
'销售额': [1000, 1500, 800, 1200, 900, 1100],
'日期': ['2023-01', '2023-01', '2023-02', '2023-02', '2023-03', '2023-03']
})
# 按销售员拆分
sales_by_salesperson = {}
for name, group in sales_data.groupby('销售员'):
sales_by_salesperson[name] = group
print(f"\n销售员 {name} 的销售记录:")
print(group)
# 2.2 按行数拆分
chunk_size = 2
chunks = [sales_data[i:i+chunk_size] for i in range(0, len(sales_data), chunk_size)]
print(f"\n将数据拆分为 {len(chunks)} 个块,每块 {chunk_size} 行:")
for i, chunk in enumerate(chunks):
print(f"\n第 {i+1} 块:")
print(chunk)
# 2.3 按列拆分
df_info = sales_data[['销售员', '产品']]
df_financial = sales_data[['销售额', '日期']]
print("\n信息列:")
print(df_info)
print("\n财务列:")
print(df_financial)
# 2.4 保存为多个文件
import os
# 创建输出目录
output_dir = 'split_data'
os.makedirs(output_dir, exist_ok=True)
# 按销售员拆分并保存
for name, group in sales_data.groupby('销售员'):
filename = os.path.join(output_dir, f'sales_{name}.csv')
group.to_csv(filename, index=False, encoding='utf-8-sig')
print(f"已保存: {filename}")
# 2.5 按比例拆分数据
from sklearn.model_selection import train_test_split
train_data, test_data = train_test_split(sales_data, test_size=0.3, random_state=42)
print(f"\n训练数据 ({len(train_data)} 行):")
print(train_data)
print(f"\n测试数据 ({len(test_data)} 行):")
print(test_data)
# 3.1 读取不同格式文件
# 读取CSV
# df_csv = pd.read_csv('data.csv', encoding='utf-8')
# 读取Excel(多个sheet)
# excel_file = pd.ExcelFile('data.xlsx')
# df_sheet1 = pd.read_excel(excel_file, sheet_name='Sheet1')
# 读取JSON
# df_json = pd.read_json('data.json')
# 3.2 写入不同格式文件
# 保存为CSV
# df.to_csv('output.csv', index=False, encoding='utf-8-sig')
# 保存为Excel(多个sheet)
# with pd.ExcelWriter('output.xlsx') as writer:
# df1.to_excel(writer, sheet_name='员工信息', index=False)
# df2.to_excel(writer, sheet_name='薪资信息', index=False)
# 保存为JSON
# df.to_json('output.json', orient='records', force_ascii=False)
print("\n文件操作完成!")
def process_sales_data(file_path):
"""
综合示例:处理销售数据
"""
# 1. 读取数据
df = pd.read_csv(file_path)
# 2. 数据清洗
# 去除空格
df['销售员'] = df['销售员'].str.strip()
# 日期转换
df['日期'] = pd.to_datetime(df['日期'])
# 处理缺失值
df['销售额'] = df['销售额'].fillna(0)
# 3. 数据转换
# 添加月份列
df['月份'] = df['日期'].dt.strftime('%Y-%m')
# 添加绩效等级
conditions = [
df['销售额'] >= 1000,
df['销售额'] >= 500,
df['销售额'] < 500
]
choices = ['优秀', '良好', '待提升']
df['绩效等级'] = np.select(conditions, choices)
# 4. 数据排序
df_sorted = df.sort_values(['月份', '销售额'], ascending=[True, False])
# 5. 数据分组汇总
monthly_summary = df.groupby('月份').agg({
'销售额': ['sum', 'mean', 'max', 'min'],
'销售员': 'count'
}).round(2)
monthly_summary.columns = ['总销售额', '平均销售额', '最高销售额',
'最低销售额', '销售次数']
# 6. 拆分数据
# 按月份拆分
monthly_data = {}
for month, group in df.groupby('月份'):
monthly_data[month] = group
# 按销售员拆分
salesperson_data = {}
for person, group in df.groupby('销售员'):
salesperson_data[person] = group
return {
'原始数据': df,
'排序后数据': df_sorted,
'月度汇总': monthly_summary,
'按月拆分': monthly_data,
'按人拆分': salesperson_data
}
# 使用示例
if __name__ == "__main__":
# 创建示例数据文件
sample_data = pd.DataFrame({
'销售员': ['张三', '李四', '王五', '张三', '李四', '王五'],
'产品': ['A', 'B', 'A', 'B', 'A', 'C'],
'销售额': [1200, 800, 1500, 900, 1100, 700],
'日期': ['2023-01-15', '2023-01-20', '2023-02-10',
'2023-02-15', '2023-03-05', '2023-03-10']
})
sample_data.to_csv('sample_sales.csv', index=False, encoding='utf-8-sig')
# 处理数据
results = process_sales_data('sample_sales.csv')
print("原始数据:")
print(results['原始数据'])
print("\n排序后数据:")
print(results['排序后数据'])
print("\n月度汇总:")
print(results['月度汇总'])
# 清理临时文件
import os
if os.path.exists('sample_sales.csv'):
os.remove('sample_sales.csv')
排序技巧:
sort_values()进行单列或多列排序字符串处理:
.str访问器进行字符串操作日期时间处理:
pd.to_datetime()转换日期格式.dt访问器提取日期时间组件文件合并拆分:
merge()用于类似SQL JOIN的合并concat()用于沿轴拼接最佳实践:
这些技巧是Pandas数据处理的核心功能,掌握它们能大大提高数据处理效率。