You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中列表内正负值占比计算及Excel写入异常问题

解决交易列表的正负占比计算与Excel写入问题

首先,我们来逐个解决你遇到的两个核心问题:计算逻辑错误导致的TypeError,以及Excel写入时仅保存单个值的问题。

一、修复正负占比的计算逻辑

你最初的代码报错,是因为zip(ticker_list)的用法完全偏离了需求——它会把每个交易子列表当成独立元素迭代,导致你在判断y>=0时,把时间字符串、标的名称这些非数值型元素和0比较,自然抛出类型错误。

我们需要先按标的(比如US500)分组,再针对每个组的最后一列(盈亏数值)计算正负占比,这里提供两种可行方案:

方案1:基于列表的手动分组计算

如果坚持用列表处理,可以先构建字典按标的分组存储盈亏数据,再遍历字典计算占比:

ticker_list = [['2020.06.25 11:20:12', 'US500', 'sell', 1.0, 3047.3, '2020.06.25 11:21:32', 3051.4, 0.0, -3.89], 
               ['2020.06.25 11:20:59', 'US500', 'sell', 1.0, 3049.8, '2020.06.25 11:21:33', 3051.6, 0.0, -1.71], 
               ['2020.06.25 11:23:49', 'US500', 'sell', 1.0, 3051.6, '2020.06.25 11:25:32', 3049.7, 0.0, 1.8]]

# 按标的分组存储盈亏数据
ticker_profits = {}
for trade in ticker_list:
    ticker = trade[1]
    profit = trade[-1]
    if ticker not in ticker_profits:
        ticker_profits[ticker] = []
    ticker_profits[ticker].append(profit)

# 计算每个标的的正负占比
ticker_ratios = {}
for ticker, profits in ticker_profits.items():
    total_trades = len(profits)
    positive_count = len([p for p in profits if p > 0])
    negative_count = total_trades - positive_count
    positive_ratio = (positive_count / total_trades) * 100
    negative_ratio = (negative_count / total_trades) * 100
    ticker_ratios[ticker] = f"{positive_ratio:.1f}% positive, {negative_ratio:.1f}% negative"

# 打印结果示例
for ticker, ratio in ticker_ratios.items():
    print(f"{ticker}: {ratio}")

运行后会输出:US500: 33.3% positive, 66.7% negative,完全符合你的需求格式。

方案2:用Pandas直接分组(更简洁,推荐)

既然你的数据本来就来自DataFrame,完全没必要转成列表处理,Pandas的分组功能可以一步到位:

import pandas as pd

# 把列表转回DataFrame,自定义列名方便识别
df = pd.DataFrame(ticker_list, columns=['开仓时间', '标的', '方向', '手数', '开仓价', '平仓时间', '平仓价', '手续费', '盈亏'])

# 按标的分组,计算盈亏的正负占比
result_df = df.groupby('标的')['盈亏'].agg(
    positive_ratio=lambda x: (x > 0).mean() * 100,
    negative_ratio=lambda x: (x < 0).mean() * 100
).round(1)

# 转换成你需要的字符串格式
result_df['ratio_str'] = result_df.apply(lambda row: f"{row['positive_ratio']}% positive, {row['negative_ratio']}% negative", axis=1)

print(result_df['ratio_str'])

这种方法代码更简洁,也避免了手动处理分组的繁琐,后续写入Excel也能直接用Pandas的to_excel方法,一步完成。

二、修复Excel写入的问题

你之前的代码只保存单个值,是因为每次循环都在同一个起始行(第3行,索引从0开始对应第4行)写入,而且write_column会把单个数值重复填充,覆盖了之前的内容。正确的做法是按行逐个写入每个标的的结果,或者先整理好所有结果再一次性写入。

这里以xlwt为例(如果用openpyxl,逻辑完全一致):

import xlwt

# 用上文计算好的ticker_ratios字典
# 创建工作簿和工作表
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Profit Ratios')

# 写入表头
worksheet.write(0, 0, '标的')
worksheet.write(0, 1, '盈亏占比')

# 从第1行开始写入数据(索引从0开始)
current_row = 1
for ticker, ratio_str in ticker_ratios.items():
    worksheet.write(current_row, 0, ticker)
    worksheet.write(current_row, 1, ratio_str)
    current_row += 1  # 写完一行后,行号加1,避免覆盖

# 保存文件
workbook.save('profit_ratios.xls')

这样每个标的的结果会依次写入不同的行,不会被覆盖。另外你之前的代码里重复写了两次worksheet.write_column(3,1,pos),而且neg变量也未使用,这些细节也需要修正。

内容的提问来源于stack exchange,提问作者Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:12:37