用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()

相关推荐
卷无止境5 分钟前
WebGIS生态全景丨从浏览器里的地图到背后的空间数据库
后端·python
Y38153266211 分钟前
竞品上新监控:用搜索 API 盯住对手发布了什么新功能
python·搜索引擎
benchmark_cc11 分钟前
如何设计一个 Python 实时行情获取程序?从轮询、数据处理到量化策略接入
python·数据分析·pandas·量化交易·股票数据·quantdash
Metaphor69221 分钟前
Python 实现 Word/TXT 互转:附完整代码
python·word·格式转换·txt
柒和远方43 分钟前
DocResearch 项目面试:把每个模块讲明白,而不是背术语
python·llm·agent
信誓旦旦的程序猿1 小时前
【Python 量化取数指南 #13】Python 把行情落库:sqlite 一键存,回测随用随取
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据api
LensonYuan1 小时前
Cursor状态栏一键切换OpenAI API Key
人工智能·python·cursor
柒和远方1 小时前
DocResearch 项目理解:从一条命令到一份有出处的报告
python·llm·agent
北冥有鱼被烹1 小时前
NVIDIA DGX/HGX 服务器全景深度解析:从 H100 到 GB300,专业算力选型必读
运维·服务器·网络·python
Maiko Star1 小时前
* LangChain Agent智能体详解(上):创建调用、工具绑定与系统提示词
python·langchain·agent