将CSV中'close'列浮点值转换为累计百分比的代码修正求助
修正CSV中Close列转累计百分比的Python代码逻辑问题
看起来你现在的代码逻辑和你想要实现的累计百分比需求完全不匹配,咱们一步步来修正:
先明确你的需求
你需要:
- 第一行的
cum_p为0% - 后续每一行的
cum_p是当前close值与第一个close值的百分比差值(也就是相对于初始值的累计变化百分比),公式为:(当前close - 初始close) / 初始close * 100
如果你的需求是累计逐期涨跌幅(比如第二个值是和第一个的差值百分比,第三个是第二个到第三个的差值百分比加上前一个累计值),我也会在后面给出对应的版本。
原代码的核心问题
- 错误地使用了
timestamp列(values参数)来计算累加,完全偏离了基于close列的需求 - 硬编码了固定值
3797.14作为分母,而不是用第一个close值作为基准 - 输出的列顺序和表头不匹配,文件保存路径也存在错误
- 逻辑完全不符合“第一个值为0%,后续为与第一个值的百分比差值”的规则
修正后的代码(基于初始值的累计百分比)
import os import csv def adjust_cryptors_file(source, /, timestamp_col, close_col): # 读取CSV数据,包含表头 with open(source, 'r', newline='') as f: reader = csv.reader(f) headers = next(reader) data = list(reader) if not data: print("源CSV文件中没有数据行") return # 获取第一个close值作为基准 base_close = float(data[0][close_col]) agg_data = [] # 遍历每一行计算cum_p for row in data: timestamp = row[timestamp_col] current_close = float(row[close_col]) # 第一个值为0%,后续计算相对于基准值的百分比变化 if agg_data: cum_p = ((current_close - base_close) / base_close) * 100 else: cum_p = 0.0 # 保留两位小数(可选,根据需要调整) cum_p_rounded = round(cum_p, 2) agg_data.append([timestamp, current_close, cum_p_rounded]) # 添加表头 agg_data.insert(0, ['timestamp', 'close', 'cum_p']) # 确定保存路径 parent_dir = os.path.dirname(source) dest_path = os.path.join(parent_dir, 'modified.csv') # 写入新CSV with open(dest_path, 'w', newline='') as f: writer = csv.writer(f) writer.writerows(agg_data) print(f"修改后的文件已保存至: {dest_path}") if __name__ == '__main__': # 配置你的CSV路径和列索引(注意:CSV列索引从0开始) source_file = 'BTCUSDT-1d-data.csv' timestamp_column_index = 1 # 对应原代码的column_of_timestamp close_column_index = 5 # 对应原代码的column_of_close adjust_cryptors_file(source_file, timestamp_col=timestamp_column_index, close_col=close_column_index)
如果你需要的是累计逐期涨跌幅(比如:
- 第1行:0%
- 第2行:(C1-C0)/C0*100
- 第3行:(C1-C0)/C0100 + (C2-C1)/C1100
- ...以此类推)
可以把计算cum_p的循环部分改成这样:
# 替换原代码中计算cum_p的循环部分 prev_close = base_close total_cum_p = 0.0 for row in data: timestamp = row[timestamp_col] current_close = float(row[close_col]) if agg_data: # 计算当期涨跌幅 period_change = ((current_close - prev_close) / prev_close) * 100 total_cum_p += period_change cum_p_rounded = round(total_cum_p, 2) prev_close = current_close else: cum_p_rounded = 0.0 agg_data.append([timestamp, current_close, cum_p_rounded])
关键修改点说明
- 重新命名了参数,让逻辑更清晰(
timestamp_col和close_col) - 读取CSV时保留了表头,确保数据处理更规范
- 使用第一个
close值作为基准,替代硬编码的固定值 - 修正了列顺序,确保表头和数据对应
- 修复了文件保存路径的错误,现在会正确保存到源文件的父目录
- 添加了空数据的判断,避免报错
- 对百分比结果做了四舍五入,让输出更整洁(可根据需求调整小数位数)
内容的提问来源于stack exchange,提问作者Martin RL
相关产品推荐
相关产品推荐

