欢迎光临韵绾网
详情描述
Pandas 基础使用指南:排序、字符串/日期处理和文件合并拆分

一、数据排序技巧

1. 基础排序方法

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)

2. 高级排序技巧

# 创建包含缺失值的示例数据
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)

二、字符串数据处理

1. 基础字符串操作

# 创建包含字符串的数据
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. 高级字符串操作

# 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[['电话', '提取数字', '邮箱', '是否有效邮箱']])

三、日期时间处理

1. 日期时间基础操作

# 创建包含日期时间的数据
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. 日期时间计算和操作

# 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']])

四、文件合并与拆分

1. 数据合并操作

# 创建示例数据
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. 数据拆分操作

# 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. 文件读写操作

# 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()用于沿轴拼接
  • 掌握按条件、按行数、按列的拆分方法

最佳实践

  • 始终指定编码格式(推荐utf-8-sig)
  • 处理缺失值后再进行排序和分析
  • 使用合适的数据类型以减少内存占用
  • 定期保存中间结果以防止数据丢失

这些技巧是Pandas数据处理的核心功能,掌握它们能大大提高数据处理效率。