在日常办公和数据分析中,Excel和CSV文件是最常见的数据载体。作为财务分析师,我每周都要处理上百份报表;做市场调研时,需要合并几十个渠道的销售数据;做用户分析时,要清洗来自不同系统的CSV日志。手动操作不仅效率低下,还容易出错。
Python的pandas库提供了强大的表格处理能力。通过几行代码就能实现:
最近我用它3小时完成了过去需要2天的手工工作,准确率还提升到100%。下面分享具体实现方法。
推荐使用Anaconda发行版,它预装了数据分析常用库。新建环境时建议:
bash复制conda create -n data_processing python=3.8
conda activate data_processing
pip install pandas openpyxl xlrd
版本选择考量:
Jupyter Notebook适合交互式调试:
python复制# 单元格内实时查看数据
df.head()
VS Code更适合大型项目:
多文件合并的三种方案:
python复制import glob
files = glob.glob('./sales/*.xlsx')
df_list = [pd.read_excel(f) for f in files]
result = pd.concat(df_list, ignore_index=True)
python复制df1 = pd.read_csv('user_info.csv')
df2 = pd.read_excel('order_records.xlsx')
result = pd.merge(df1, df2, on='user_id')
python复制with pd.ExcelFile('multi_sheet.xlsx') as xls:
df1 = pd.read_excel(xls, 'Sheet1')
df2 = pd.read_excel(xls, 'Sheet2')
重要提示:读取大文件时使用
chunksize参数分块处理,避免内存溢出
典型清洗场景及处理方案:
| 问题类型 | 处理方法 | 示例代码 |
|---|---|---|
| 空值处理 | 填充/删除 | df.fillna(0) / df.dropna() |
| 格式转换 | 类型强制转换 | df['price'] = df['price'].astype(float) |
| 异常值 | 条件过滤 | df = df[df['age'] < 100] |
| 重复值 | 去重处理 | df.drop_duplicates() |
| 字符串处理 | 正则表达式 | df['phone'] = df['phone'].str.replace(r'\D', '') |
python复制monthly_stats = df.groupby(['year', 'month']).agg({
'sales': ['sum', 'mean'],
'profit': 'median'
})
python复制pivot_table = pd.pivot_table(
df,
values='revenue',
index='region',
columns='quarter',
aggfunc=np.sum,
fill_value=0
)
python复制df['discount'] = np.where(
df['amount'] > 1000,
df['amount'] * 0.9,
df['amount']
)
多场景输出方案:
python复制# 单个CSV输出
df.to_csv('output.csv', index=False, encoding='utf-8-sig')
# 分表Excel输出
with pd.ExcelWriter('report.xlsx') as writer:
df1.to_excel(writer, sheet_name='Summary')
df2.to_excel(writer, sheet_name='Details')
# 按条件拆分文件
for region, group in df.groupby('region'):
group.to_excel(f'{region}_data.xlsx')
python复制from openpyxl.styles import Font, Alignment
for cell in ws['A']:
cell.font = Font(bold=True)
cell.alignment = Alignment(horizontal='center')
python复制# 保留中文编码
df.to_csv('data.csv', encoding='utf_8_sig')
# 自定义分隔符
df.to_csv('data.txt', sep='|')
python复制# 查看类型内存占用
df.memory_usage(deep=True)
# 优化数值类型
df['id'] = df['id'].astype('int32')
df['price'] = pd.to_numeric(df['price'], downcast='float')
python复制from multiprocessing import Pool
def process_file(file):
return pd.read_excel(file).query('sales > 1000')
with Pool(4) as p:
results = p.map(process_file, file_list)
大文件处理策略:
python复制chunks = pd.read_csv('huge.csv', chunksize=100000)
for chunk in chunks:
process(chunk)
python复制import dask.dataframe as dd
ddf = dd.read_csv('*.csv')
result = ddf.groupby('category').sum().compute()
某零售企业需要:
python复制# 合并文件
all_data = []
for file in Path('daily_reports').glob('*.xlsx'):
df = pd.read_excel(file, parse_dates=['date'])
df['store'] = file.stem.split('_')[0]
all_data.append(df)
combined = pd.concat(all_data)
# 计算周报
weekly = (combined
.groupby([pd.Grouper(key='date', freq='W'), 'category'])
.agg({'amount': 'sum', 'profit': 'mean'})
.reset_index()
)
# 格式处理
with pd.ExcelWriter('weekly_report.xlsx') as writer:
weekly.to_excel(writer, sheet_name='Data', index=False)
workbook = writer.book
worksheet = writer.sheets['Data']
# 设置表头样式
header_format = workbook.add_format({
'bold': True,
'border': 1,
'bg_color': '#D7E4BC'
})
for col_num, value in enumerate(weekly.columns.values):
worksheet.write(0, col_num, value, header_format)
# 设置数字格式
money_fmt = workbook.add_format({'num_format': '$#,##0'})
worksheet.set_column('C:D', 15, money_fmt)
# 发送邮件(略)
utf_8_sig编码parse_dates参数float_format='%.2f'chunksize分块处理dtype=objectpython复制# 错误写法(Windows反斜杠问题)
df = pd.read_csv('C:\data\file.csv')
# 正确写法
from pathlib import Path
df = pd.read_csv(Path('data/file.csv'))
python复制# 错误方式
if df['col'] == None:
# 正确方式
if pd.isna(df.at[0, 'col']):
python复制# 修改副本不会影响原数据
df[df.age > 30]['flag'] = 1 # 无效
# 应该使用loc
df.loc[df.age > 30, 'flag'] = 1
python复制# 读取SQL数据
import sqlalchemy
engine = sqlalchemy.create_engine('postgresql://user:pass@localhost/db')
df = pd.read_sql('SELECT * FROM sales', engine)
# 写入数据库
df.to_sql('new_table', engine, if_exists='replace')
python复制# Windows任务计划
schtasks /create /tn "ProcessReports" /tr "python process.py" /sc daily /st 09:00
# Linux crontab
0 9 * * * /usr/bin/python3 /path/to/process.py
python复制import matplotlib.pyplot as plt
df.plot(kind='bar', x='month', y='sales')
plt.savefig('trend.png')
经过多个项目的实战检验,我总结出最关键的三个经验:始终做好数据备份、使用Path对象处理文件路径、在复杂操作前先用小样本测试。当处理十万行以上的数据时,这些习惯能节省大量调试时间。