用python整理excel文件交易记录

华泰证券0412-0612-按年.xlsx 文件中保存了所有股票交易记录,例如:这样的记录:

编写python程序,现在从中提取,一个股票一个SHEET页面,存放这个股票所有的交易记录

把所有无法提取,或者异常记录都保存到一个 异常 sheet页面中

输出 整理.xlsx

把一个按年份分sheet 的股票交易流水文件(比如2004年一个sheet、2005年一个sheet......),重新整理成按股票分sheet的新文件(兰州铝业一个sheet、四川长虹一个sheet......),异常数据单独放一个"异常"sheet。

import pandas as pd

import openpyxl

from openpyxl.utils import get_column_letter

INPUT_FILE = "华泰证券0412-0612-按年.xlsx"

OUTPUT_FILE = "整理.xlsx"

def main():

xl = pd.ExcelFile(INPUT_FILE)

all_dfs = \[\]

for sheet_name in xl.sheet_names:

df = pd.read_excel(INPUT_FILE, sheet_name=sheet_name, dtype=str)

df'_源SHEET' = sheet_name

all_dfs.append(df)

data = pd.concat(all_dfs, ignore_index=True)

所有单元格内容 trim 一下

try:

data = data.map(lambda v: v.strip() if isinstance(v, str) else v)

except AttributeError:

data = data.applymap(lambda v: v.strip() if isinstance(v, str) else v)

data.columns = str(c).strip() for c in data.columns

expected_cols = '日期', '币种', '股票名称', '股票代码', '业务标志', '发生数量', '成交均', '收付金额', '资金余额'

if '成交均价' in data.columns and '成交均' not in data.columns:

data = data.rename(columns={'成交均价': '成交均'})

for c in expected_cols:

if c not in data.columns:

datac = None

数字列转为数值类型

int_cols = '发生数量'

float_cols = '成交均', '收付金额', '资金余额'

for c in int_cols + float_cols:

datac = pd.to_numeric(datac, errors='coerce')

for c in int_cols:

datac = datac.astype('Int64')

normal_rows = \[\]

abnormal_rows = \[\]

for idx, row in data.iterrows():

code = row.get('股票代码')

name = row.get('股票名称')

date = row.get('日期')

if pd.isna(code) or code == '' or pd.isna(name) or name == '' or pd.isna(date) or date == '':

abnormal_rows.append(row)

else:

normal_rows.append(row)

数字格式

int_fmt = '0'

float_fmt = '0.00'

def apply_number_format(ws, cols):

header = cell.value for cell in ws\[1]

for col_idx, col_name in enumerate(header, 1):

if col_name in int_cols:

fmt = int_fmt

elif col_name in float_cols:

fmt = float_fmt

else:

continue

for row_cells in ws.iter_rows(min_row=2, min_col=col_idx, max_col=col_idx):

for cell in row_cells:

cell.number_format = fmt

with pd.ExcelWriter(OUTPUT_FILE, engine='openpyxl') as writer:

used_names = set()

if normal_rows:

normal_df = pd.DataFrame(normal_rows)

for name, grp in normal_df.groupby('股票名称'):

sheet_name = str(name)

for ch in '/', '\\\\', '?', '\*', '\[', '', ':']:

sheet_name = sheet_name.replace(ch, '_')

sheet_name = sheet_name:31

base = sheet_name

cnt = 1

while sheet_name in used_names:

cnt += 1

suffix = f"_{cnt}"

sheet_name = (base:31-len(suffix)) + suffix

used_names.add(sheet_name)

正常页:只输出标准列,不包含 _源SHEET

out = grpexpected_cols.copy()

out = out.sort_values(by='日期', key=lambda s: s.astype(str))

out.to_excel(writer, sheet_name=sheet_name, index=False)

异常页:包含 _源SHEET 列

if abnormal_rows:

ab_df = pd.DataFrame(abnormal_rows)

ab_cols = expected_cols + '_源SHEET'

ab_cols = c for c in ab_cols if c in ab_df.columns

ab_dfab_cols.to_excel(writer, sheet_name='异常', index=False)

else:

pd.DataFrame(columns=expected_cols).to_excel(writer, sheet_name='异常', index=False)

设置列宽 + 数字格式

wb = openpyxl.load_workbook(OUTPUT_FILE)

for ws in wb.worksheets:

apply_number_format(ws, expected_cols)

for col_idx, col_cells in enumerate(ws.columns, 1):

max_len = 0

for cell in col_cells:

if cell.value is not None:

l = len(str(cell.value))

if l > max_len:

max_len = l

ws.column_dimensionsget_column_letter(col_idx).width = min(max_len + 2, 30)

wb.save(OUTPUT_FILE)

print(f"完成!输出文件:{OUTPUT_FILE}")

print(f"正常记录:{len(normal_rows)}, 异常记录:{len(abnormal_rows)}")

print(f"股票 sheet 数:{len(wb.sheetnames) - 1}")

if name == 'main':

main()

相关推荐
Thanks_ks10 小时前
【第 006 讲】搭建 PyCharm 开发环境:PyCharm 的下载与安装 | 初始设置与常用配置
ide·python·pycharm·开发工具·jetbrains·开发环境·集成开发环境
青少儿编程课堂11 小时前
蓝桥杯青少组图形化省考报名倒计时·全国青少年信息素养大赛·电子学会图形化考级:校园黑白棋人机对战解析
c++·python·算法·bfs·信息学竞赛
tellmewhoisi11 小时前
nlp:知识库检索和dify知识库创建
python·自然语言处理
2601_9687931412 小时前
Python Requests 轻量自动化:无需浏览器,实现真人级账号浏览模拟
开发语言·python·自动化
段一凡-华北理工大学21 小时前
工业智能体:从Codex/Claude到项目实战~系列文章05:从“AI助手“到“工业智能体“:能力跃迁与落地范式
人工智能·python·claude·codex·工业智能体·高炉炼铁智能化
深蓝AI21 小时前
ContextVar 到线程池就丢了?asyncio.to_thread 和 run_in_executor 实测
python
岁月宁静1 天前
什么是 Agent:从"会聊天"到"会做事"
人工智能·python
岁月宁静1 天前
AI 应用开发工程师简历怎么写:HR 初筛、技术复筛、面试追问,三道关卡各看什么?
人工智能·python·面试
来让爷抱一个1 天前
Python 异步里混用同步库,事件循环被卡住的全过程
开发语言·python
小肝一下1 天前
3.基础语法(3)
python